【发布时间】:2022-07-06 20:14:57
【问题描述】:
当使用 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\"
并且您不想使用 PATCH 删除国家/地区:
\"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\'s Optionals。
注意:我正在寻找一个更结构化的解决方案,它也适用于 api 中的所有其他资源(10 多个类)。
-
对于 UPDATE 请求,我会收到
JsonObject并遍历所有已知键以确定如何更新它们。 -
感谢您的回复。这确实是一种选择,但是当存在分层结构时(例如,将 MyAddress 作为 Person 的值,而 Person 是 Group 的值),您必须“知道”所有键的名称。我认为这不是真正可扩展的。
-
然后我在这里看到两个选项。要么让所有属性为空但没有默认值,并强制客户端每次都发送所有键,要么只使用 JSON 元素对象始终如一地工作。
-
第一个选项不会真正起作用,因为从用户/API 的角度来看,这不是 REST 应该如何工作的。我希望有一个更有条理的解决方案。就像 Kotlin 有(它已被删除)一个
Optional注释一样。类似的东西,具有与 Java Optional 相同的“功能”;您可以确定 1) 发送时带有值,2) 发送时带有null值,3) 未发送
标签: api rest kotlin optional ktor