If a property is null, usually it is not necessary for client(at least javascript web app), only consumes network traffic of remote server such as ktor.
Hope add a Json configuration not serialize all null properties:
val format = Json { ignoreNull = true } //default can be false
then
@Serializable
class Project(val name: String, val renamedTo: String?)
fun main() {
val data = Project("kotlinx.serialization", null)
println(Json.encodeToString(data))
}
output:
{"name":"kotlinx.serialization"}
You can always set defaults to allow eliding properties. Handling null properties as you request is possible, but not trivial. Decoding requires recording all read properties and generating synthetic events for the nullable values.
You can set null as a default value of your nullable property and use encodeDefaults = false as shown with an example here: https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/json.md#encoding-defaults
Does it work for you?
You can set
nullas a default value of your nullable property and useencodeDefaults = falseas shown with an example here: https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/json.md#encoding-defaultsDoes it work for you?
encodeDefaults = false remove all keys which have default value include non-null, as following:
@Serializable
class Project2(val name: String, val renamedTo: String? = null, val level: Int = 100)
fun test2(){
val json = Json{ encodeDefaults = false }
val data = Project2("kotlinx.serialization")
//output: {"name":"kotlinx.serialization"}, remove the key: level
println(json.stringify(Project2.serializer(), data))
}
The feature of Include.NON_NULL in Jackson is expected.
You can always set defaults to allow eliding properties. Handling null properties as you request is possible, but not trivial. Decoding requires recording all read properties and generating synthetic events for the nullable values.
When deserialize, if no key-value in json string , default value in constructor will be used. If no default value, programmer should be responsible for the failure of deserialization, which is similar to the behavior of Include.NON_NULL in Jackson.
In client-server application, null values in api provided by server are valueless for front end web app.
@rwsbillyang
encodeDefaults = falseremove all keys which have default value include non-null, as following:
Yes, can you, please, give a bit more concrete example on what kind of problem this creates in your particular domain? How you have a situation where where null defaults should not be encoded, but non-null default still should be encoded? Do you have a lot of those "non-null must be encoded" default in your data model?
@rwsbillyang
encodeDefaults = falseremove all keys which have default value include non-null, as following:Yes, can you, please, give a bit more concrete example on what kind of problem this creates in your particular domain?
How you have a situation where wherenulldefaults should not be encoded, but non-null default still should be encoded?
Yes, the expect feature is: non-null should be encoded, null should not be encoded, not considering they are default or not.
Do you have a lot of those "non-null must be encoded" default in your data model?
Yes. One example: Remote server(eg. ktor) provides API, send json response to client(eg. React web app). Maybe there are lots of properties in a data model, but most properties usually are null . For client, these null properties totally can be ignored, but client doesn't know the default non-null values, so all non-null properties, include non-null default, should be encoded.
There will be a big benefit(at least save network bandwidth) from the feature especially if there are high-frequency API requests from clients daily.
The reason I'm asking it that the specific value of the default is opaque to Kotlin Serialization. null or not null default is the same. They are all equally good default values. What we can do is to add a feature where you can override a global encodeDefaults on a per-field basis with some annotation. This way, for example, you can globally set encodeDefaults = false, but if you see a case in your server code that has some server-specific default value that the client is unaware about (maybe because of some compatibility reasons that the client app was built with the old version of API that had a different default or no default at all and the property was required) you can apply some field-specific @EncodeDefault annotation to this field to force this specific field to be always encoded. Will it help you?
btw, isn't this a duplicate of #195 ?
The reason I'm asking it that the specific value of the default is opaque to Kotlin Serialization.
nullor notnulldefault is the same. They are all equally good default values. What we can do is to add a feature where you can override a globalencodeDefaultson a per-field basis with some annotation. This way, for example, you can globally setencodeDefaults = false, but if you see a case in your server code that has some server-specific default value that the client is unaware about (maybe because of some compatibility reasons that the client app was built with the old version of API that had a different default or no default at all and the property was required) you can apply some field-specific@EncodeDefaultannotation to this field to force this specific field to be always encoded. Will it help you?
@elizarov, thank you for your technical explantation and suggestion. I get a workaround solution to reach the goal:
set encodeDefaults = false, and do more a bit programming work : set default null for all properties which possibly are null. If any one of them is non-null, set the non-null value for it by hand. The result is all null properties are ignored. The solution is at least available for API one-way output response to JavaScript client.
Thanks again.
btw, isn't this a duplicate of #195 ?
Yes, it's duplicated.
Then, if you do not mind, I'll close the discussion here in favor of the original issue.
Most helpful comment
encodeDefaults = falseremove all keys which have default value include non-null, as following:The feature of Include.NON_NULL in Jackson is expected.