Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to always ignore nulls and empty collections when writing to JSON (regardless whether they are optional or not) #195

Closed
qwwdfsad opened this issue Aug 15, 2018 · 22 comments
Assignees

Comments

@qwwdfsad
Copy link
Collaborator

No description provided.

@sandwwraith
Copy link
Member

#58 , isn't it?

@qwwdfsad
Copy link
Collaborator Author

This one has JSON-only scope and doesn't affect optionality/default values

@LouisCAD
Copy link
Contributor

I can currently use the following for null values:

val json = Json(encodeDefaults = false)

That applies to all models though, no way to specify it on a per-property basis, and no support for empty collections.
Maybe the title should specify "per property" if that's the intention, or drop the reference to "nulls" otherwise?

@anschnapp
Copy link

I guess...

val json = Json(encodeDefaults = false)

... is not for the exact same use case.
It would allow the ignore null values if they are the default value.
But it would also ignore all other default values which might not be null.

I'm currently searching for a solution where null values will not be part of the json, but I want to have other default values (like strings) be part of the json, so that they could be read from the consumer side.

@francos
Copy link

francos commented Jul 15, 2019

Is there a workaround for this? (apart from Json(encodeDefaults = false))

@LouisCAD
Copy link
Contributor

@FrancoSabadini Writing a custom serializer and applying it to the relevant properties. It's quite easy to do if you look at the doc, although it might be redundant if you have to apply it to many properties.

@francos
Copy link

francos commented Jul 15, 2019

Thanks for the answer @LouisCAD.

Yes, I have to add it to quite a few properties so it gets a bit annoying. Can you point me to the specific doc you are referring to? And what would this custom serializer look like?

@matejdro
Copy link

encodeDefaults solution does not appear to apply to nulls:

@Serializable
data class Test(val value: String?)

fun main() {
    val json = Json(
        JsonConfiguration(encodeDefaults = false)
    )

    println(json.toJson(Test.serializer(), Test(null)))
}

prints out

{"value":null}

@Dominaezzz
Copy link
Contributor

That needs to be,

@Serializable
data class Test(val value: String? = null)

@matejdro
Copy link

Thanks, what about when passing in null explicitly?

@Dominaezzz
Copy link
Contributor

If you only pass null explicitly, then it's not a default, so it is encoded. But by telling kotlinx.serialisation that the default is null, it knows not to encode it when encodeDefaults = false is specified.

@matejdro
Copy link

matejdro commented Jul 30, 2019

Yes, but title of the issue says Allow to ignore nulls, not Allow to ignore null defaults

I was just commenting on another flaw of this workaround.

@sandwwraith sandwwraith changed the title Allow to ignore nulls and empty collections when writing to JSON Allow to always ignore nulls and empty collections when writing to JSON (regardless whether they are optional or not) Aug 13, 2019
@bizarre
Copy link

bizarre commented Feb 17, 2020

Any update on this?

@molind
Copy link

molind commented Mar 26, 2020

We do have a lot of default values. And they all are important. At the same time we do have some null values. And they could be skipped. It's a common feature among other languages. Default behavior in Swift and could be easy turned on in Go:
a bool json:",omitempty"

@frne
Copy link

frne commented Jul 28, 2020

Any news on this? In the JSON world, {prop: null} and { } is not the same. Because of that, it's a real showstopper for some projects, which need to comply to a JSON schema.
Please ping me if I can help to get (coding-) work done ;)

@arberg
Copy link

arberg commented Sep 22, 2020

I'm also in a situation where the encodeDefaults is not the same for me as encodeNulls.

I have some defaults set to 0 (some Ints), where the server requires those 0's to be sent. So I need encodeDefaults = true, because I also use those Dto's for receiving data from the server, so I can't remove the default value on the constructor.

But I would greatly appreciate getting rid of null-encodings, as it generates spam in the dto sent to the server and written in logs.

@qwwdfsad
Copy link
Collaborator Author

We plan to work on it somewhere around 1.1

@carlosezam
Copy link

Any update on this?

@sandwwraith
Copy link
Member

@carlosezam Unfortunately, this feature is not being developed in the moment

@DavyHubrecht
Copy link

DavyHubrecht commented Jan 26, 2021

I agree this feature should be added and should be completely separate from the "encodeDefaults = true" option.

Consider this code:

data class SomeDataClass(
        val requiredField: String,
        val timeout:Int = 30,
        val someOptionalValue: String? = null,
        val anotherOptionalValue: String? = null
)

val instance = SomeDataClass("some_value")

By default this would output this json:

{
  "requiredField": "some_value"
}

Which is not what we want, because it misses the "timeout" property. Keep in mind that the consumer of this API does not necessarily know the default value.

The alternative would be to use encodeDefaults = true, which outputs this json:

{
  "requiredField": "some_value",
  "timeout": "30",
  "someOptionalValue": null,
  "anotherOptionalValue": null
}

Which is also not something we want, as this causes extra clutter, especially for data classes with a lot properties with null as a default.

My proposal would be to add a new option (eg: encodeNulls), which is true by default for backwards compatability, but would remove all nulls if set to false. It would then output this json:

{
  "requiredField": "some_value",
  "timeout": "30"
}

We're currently converting our JVM Kotlin project to a Multiplatform one. We used gson before, where this was a possibility, but we found no way to do this using kotlinx.serialization.

@mboudraa
Copy link

Any news on this?
Right now it requires a custom serializer to achieve this where a simple configuration property should be enough

@ArcticLampyrid
Copy link

ArcticLampyrid commented May 8, 2021

Providing EncodeDefault annotation per field can be helpful to this situation.
@DavyHubrecht
#1091

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests