当使用Ktor(和Kotlin)实现REST API时,它支持Kotlin的可选字段处理。哪个适用于POST和GET,但是PATCH(更新)呢?
例如,您有以下资源:
@Serializable
data class MyAddress(
var line1: String? = null,
var line2: String? = null,
var city: String? = null,
var postal_code: String? = null,
var state: String? = null,
var country: String? = null
)
因此所有MyAddress字段都是可选的(具有默认值)。
使用POST创建地址时:
"line1" : "line1",
"country" : "XX"
你想用补丁删除这个国家:
"country" : null
资源的最终结果应该是:
"line1" : "line1"
但是如何通过解析PATCH请求的json来确定这一点呢?因为据我所知,没有办法确定它是默认的null
,还是提交的。
此外,MyAddress
的默认null
值是必需的,否则解析将无法工作。
代码示例:
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
@kotlinx.serialization.Serializable
data class MyAddress(
var line1: String? = null,
var line2: String? = null,
var city: String? = null,
var postal_code: String? = null,
var state: String? = null,
var country: String? = null
)
fun main() {
val jsonStringPOST = "{\"line1\":\"street\",\"country\":\"GB\"}"
println("JSON string is: $jsonStringPOST")
val myAddressPost = Json.decodeFromString<MyAddress>(jsonStringPOST)
println("MyAddress object: $myAddressPost")
val jsonStringPATCH = "{\"country\":null}"
println("JSON string is: $jsonStringPATCH")
val myAddressPatch = Json.decodeFromString<MyAddress>(jsonStringPATCH)
println("MyAddress object: $myAddressPatch")
}
我也尝试添加Optional<String>?
,但它抱怨缺少Optional
的序列化,最好我不想让所有数据都成为var的Optional。
注意:我正在寻找一个更结构化的解决方案,也与所有其他资源的API(10+类)。
4条答案
按热度按时间eh57zj3b1#
第二个解决方案,基于Aleksei的例子:
输出为:
5ssjco0h2#
您可以使用sealed interface作为地址的一部分,以表示未定义的值,缺少值和实际值。对于这个接口,您需要编写一个序列化程序,它将根据您的逻辑对值进行编码和解码。我不擅长
kotlinx.serialization
框架,所以我写了一个尽可能简单的例子。nbysray53#
在www.example.com的帮助下medium.com,我得到了以下解决方案:
这将打印:
mwkjh3gx4#
第三种解决方案基于Etienne。它修复了解码器不能被反序列化为T并抛出的问题。基础版本Map为“不存在”。
还重新命名了病例。