Hi all,
Late last year I initiated the topic: [Pre-pitch] Roundtripping key coding strategies.
The topic highlights a well known issue with the current .convertToSnakeCase
keyEncodingStrategy
of JSONEncoder
and .convertFromSnakeCase
keyDecodingStrategy
of JSONDecoder
.
I will highlight the issue here with examples from the linked topic.
The core issue is that not all keys round-trip.
As an example, consider the following struct:
struct Person: Codable {
var imageURL: URL
}
Using .convertToSnakeCase
with JSONEncoder
will produce:
{
"image_url": "..."
}
But the corresponding decoding will go from snake case to camel case by a fixed algorithm, trying to look up the key: imageUrl
, which does not exist.
This is a common source of bugs when using key coding strategies, and at least in code bases that I am familiar with, the workaround is often to add custom coding keys like:
enum CodingKeys: String, CodingKey {
case imageURL = "imageUrl"
}
This allows the imageURL property to roundtrip when used with the snake case encoding and decoding, but this is a 'leaky abstraction'.
Codable
entities and the encoder/decoder they are used with are supposed to be decoupled, but in this situation, the developer needs to know if the codable entity is used with an encoder/decoder pair that use key transformations - and also need to remember to map the key correctly, so that it will be 'found' when converting back from snake case to camel case.
Often I have seen attempts to 'fix' the behavior with the notation you would use if you didn't apply a key coding strategy:
enum CodingKeys: String, CodingKey {
case imageURL = "image_url"
}
which of course is no good when used with snake case conversion, since the key that will be looked up is "imageUrl".
In other words: the work-around to fix this issue is a bit counter-intuitive and also has the issue that you 'tie' the coding key to a specific encoding/decoding use case.
Although the issue is in the domain of Foundation, I can't see a fix to the issue that does not also involve the Swift standard library and this was the reasoning for bringing up the topic in the first place.
After a small bit of welcome feedback I turned the pre-pitch into a pitch ([Pitch] Roundtripping key coding strategies) and got a slight bit of extra feedback.
I presented the possible SE proposal to the Core Team where I received some very appropriate feedback:
My initial 'pre-pitch', 'pitch' and SE proposal were all presented in these forums in a very formal style - and with lists of pros and cons that left little room for discussion or engagement from the community and possibly from the Foundation team.
So now I would like to re-open the discussion, but hopefully in a style that allows more people to engage.
The questions I would like help answering are:
- Is this issue big enough to warrant a fix?
- Can the issue be fixed in Foundation alone? How could such fixes look?
- Would a fix require changes to the standard libraries? How could such fixes look? Is the issue big enough to warrant changes to the
Codable
system in the standard libraries?
I'll take the liberty to tag some of the commenters of the previous topics:
@itaiferber @gwendal.roue @Nickolas_Pohilets @hisekaldma @tomerd
Any feedback is more than welcome, and I hope to be able to engage people from the Foundation team too.