[swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode
Itai Ferber
iferber at apple.com
Wed Aug 30 13:22:34 CDT 2017
Hi Brandon,
Thanks for looking at this! We’ve got plans internally to potentially
add a strategy to `JSONEncoder`/`JSONDecoder` to allow lenient
conversions like this — i.e. implicitly stringify numbers (or parse
them from string input), among some others.
This would be opt-in for consumers of `JSONDecoder` while not requiring
any special annotations on `Codable` types.
— Itai
On 30 Aug 2017, at 10:59, Sneed, Brandon via swift-corelibs-dev wrote:
> Hi everyone,
>
> Just throwing this out to see if anyone else is working on this, or
> has opinions/suggestions on how it’s implemented. I’d like to add
> this to the Codable/JSONDecoder/JSONEncoder system if no one else is
> working on it.
>
> Type type conversion, I mean given this JSON payload:
>
> {
> "name": "Endeavor”,
> "abv": 8.9,
> "brewery": "Saint Arnold”,
> "style": "ipa"
> }
>
> and a struct defined as:
>
> struct Beer: Codable {
> let name: String
> let abv: String
> let brewery: String
> let style: BeerStyle
> }
>
> Notice that “abv” is a number in the JSON, but a String in the
> struct. I’d like to make it such that I can let the system know
> it’s ok to convert it from a number to a string as opposed to
> throwing an exception. The benefits are:
>
> 1. It’s defensive; service types can change without causing my
> application to crash.
> 2. It allows a developer to work with the types they want to
> work with as opposed to what the server provides, thus saving them
> time of writing a custom encode/decode code for all members.
>
> The argument against it that I’ve heard is generally “it’s a
> service bug, make them fix it”, which is valid but the reality is
> we’re not all in control of the services we injest. The same type
> of logic could be applied to a member name changing, though I
> haven’t seen this happen often in practice. I do see types in a
> json payload change with some frequency though. I think much of the
> reason stems from the fact that type conversion in javascript is
> effectively free, ie: you ask for a String, you get a String if
> possible.
>
> To implement this type conversion in practice, looking at it from the
> point of view using Codable/JSON(en/de)coder, one way would be to make
> it opt-in:
>
> struct Beer: Codable, CodingConvertible {
> let name: String
> let abv: String
> let brewery: String
> let style: BeerStyle
> }
>
> I like this because looking at the struct, the members still remain
> clear and relatively unambiguous. The downside is it’s unknown
> which member is likely to get converted. And since it’s opt-in,
> conversion doesn’t happen if the CodingConvertible conformance
> isn’t adhered to.
>
> Another option would be to box each type, like so:
>
> struct Beer: Codable {
> let name: String
> let abv: Convertible<String>
> let brewery: String
> let style: BeerStyle
> }
>
> This seems tedious for developers, but would show which types are
> being converted. It does however seriously weaken benefit #1 above.
>
> Those example usages above aside, I do think it’d be best if this
> conversion behavior was the default and no end-developer changes
> required. I think that could be done without impact to code that’s
> been already been written against the JSON en/decode bits.
>
> I’m very open to alternatives, other ideas, or anything else you
> might have to say on the subject. Thanks for reading!
>
>
>
> Brandon Sneed
> _______________________________________________
> swift-corelibs-dev mailing list
> swift-corelibs-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-corelibs-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-corelibs-dev/attachments/20170830/46fa8415/attachment.html>
More information about the swift-corelibs-dev
mailing list