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
[SR-9232] Optionals with nil value do not get encoded to JSON #3594
Comments
You can always write cc @itaiferber in case he has anything to add |
Comment by Peter de Kraker (JIRA) Yes, I understand that it can be done manually, but in my use case, and probably for a lot of other people, I have a API with lots of inputtypes, that I just want to match with simple data classes. To manually code the encode of everyone is a lot of work, and that's where Swift could (and should 🙂 ) make it easier on the developer. Especially because removing nils afterwards is easy, adding them is not. Why assume that API's dont take nulls in JSON? Isn't that a bit unrealistic? |
The assumption isn't necessarily just that APIs don't take nulls, but also that many treat null and absent as interchangeable, and that smaller payloads are better. If Swift is both the encoder and the decoder, for example, both of these are the case. |
Comment by Sergey Balalaev (JIRA) I think it's would be better, if we take a option as |
Comment by Mukesh (JIRA) Would second sof.bix (JIRA User). For example rest api's have PATCH method, where only partial body is sent and if nulls are discarded, there wouldn't be a way to make an value null once it has been entered even if it optional. |
Comment by Jon M Snyder (JIRA) The difference between a client of an API knowing about something and setting it to |
Comment by Jens Miltner (JIRA) I would also like to second sof.bix (JIRA User) - not always are we in control of both frontend and backend and if backend treats null values and missing values differently, it's currently a pain to have to add a custom encode(to🙂 just to encode those null values (especially if there are a lot of different structs) |
Comment by Nicolai Cornelis (JIRA) I was pretty surprised to find that nils simply get thrown away as if they're meaningless. This is not really a great design choice in my opinion. The main benefit of using Encodable/Decodable is that you don't have to write all of the code for serialisation. Now we have to do it anyway if we have situations where an API expects null - or where null means something different than absent. This could be "change this property to null" vs. "don't change this property". I like Sergey's suggestion. Please take another look at this. |
Comment by Johan Nordberg (JIRA) I also second Sergey's There is a third-party JSONEncoder in FineJSON that allows you to encode Optionals as EDIT: Just in case someone else who reads this tries to implement a custom Encoder that handles nil values. This might be obvious for people more familiar with Swift's type system but it took me for a spin: You need to implement all 13 specialized versions of |
Comment by Ben D. Jones (JIRA) @swift-ci sync |
Comment by Nicolai Cornelis (JIRA) Hello Any updates on this? This is currently quite the headache for us. |
This is a huge issue for my team as well, as our back end uses explicit nil values for certain purposes. |
Comment by Steven Grosmark (JIRA) As a work-around, I've been using a property wrapper, along the lines of: @propertyWrapper
public struct NullCodable<Wrapped: Encodable>: Encodable {
public var wrappedValue: Wrapped?
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch wrappedValue {
case .some(let value): try value.encode(to: encoder)
case .none: try container.encodeNil()
}
}
struct Test: Encodable {
@NullCodable var name: String? = nil
}
JSONEncoder().encode(Test()) // -> "{\"name\": null}"
Not ideal, since each optional property needs to be marked, but it is a little easier than trying to implement a custom encoder. I created a small package for it here: NullCodable. |
Comment by Marcin Iwanicki (JIRA) There are pros and cons of both cases. Omitting optional properties results in a smaller payload. JSON format is frequently used in the networking layer as such the size of the payload matters. I think it would be great to preserve the current behavior as default and avoid breaking changes. Adding a new property e.g. |
One more Reason to stop developing in Swift and start using React to develop your Apps! I don't get it why Apple cannot implement this simple stuff like other Languages did it ... |
This actually just caused us a pretty nasty bug. In our case we had a The problem is, omitting the key conflicts with Ruby on Rails' Strong Parameters, which take the parameters provided in the request and then filter them through a whitelist. When used in conjunction with ActiveRecord's Including the optional null keys in the JSON is helpful for a few reasons:
|
I really hope this gets added as a |
Additional Detail from JIRA
md5: d40e1037406253fafe704bc8c33c89d9
Issue Description:
The implementation of Codable and JSONEncoder in Swift 4 do automatically discard optional fields that have nil as value.
I can understand that this is an option, but there is no option to be set and that makes it a big problem for working with JSON API's that expect nulls for nil fields.
I don't really understand why this default is chosen, since removing nulls from JSON is easier afterwards, then adding them manually by needing to write the encode() method for each class.
Anyways, it would be great if an option can be provided to automatically encode nil values to null with JSONEncoder.
The text was updated successfully, but these errors were encountered: