Here is an example of what I mean.

https://go.dev/play/p/O6KIsxmSeaN

This is why I wrote a code generator, it's tedious by hand :)

On Mon, Dec 26, 2022 at 11:08 AM Marcin Romaszewicz <marc...@gmail.com>
wrote:

> This is a very annoying problem, and one that we hit a lot in my project (
> https://github.com/deepmap/oapi-codegen), where we generate Go models
> from OpenAPI specs, and the OpenAPI "AnyOf" or "OneOf" schema does
> precisely this.
>
> You can partially unmarshal; store your "type" field in a typed variable,
> and use json.RawMessage to defer parsing to later, when you know the type.
> This still gets annoying, because if your field names are dynamic, you need
> to override the default unmarshaling behavior to produce a map of field
> names to json.RawMessage. If you jump through these hoops, you can avoid
> parsing twice. Once you've partially parsed your object, you can create
> some functions on it, such as "AsAtype()" or "AsBType()", which switches on
> "type" and returns the correct concrete object.
>
> On Mon, Dec 26, 2022 at 10:04 AM Andrew Burian <and...@burian.dev> wrote:
>
>> Hey all, wondering if there's an existing best practice for this so I'm
>> not reinventing the wheel.
>>
>> It's frustratingly common to have APIs where the response JSON can be one
>> of several distinct objects, and the indicator of which object has been
>> returned is itself a property of the object.
>>
>> So you might get a `{ "type": "aType", "aField" : ."..." }` or a `{
>> "type": "bType", "bField": "..." }` response from the same API.
>>
>> What's the best way to deserialize in these situations?
>>
>> Ideas I've tried so far:
>>
>>    - Unmarhsal twice, once into a struct that just defines the `Type`
>>    property and ignores all other fields, then again based on the type set 
>> the
>>    first time.
>>    Works, but for large objects it's extremely wasteful.
>>
>>    - Unmarshal into a large struct that defines all possible subtypes as
>>    anonymous struct fields so their declarations are treated as being on the
>>    outer struct, then cast to the appropriate type after unmarshaling to mask
>>    all the unfilled fields.
>>    Again, works, but feels awful. It also presents a real issue when you
>>    need to verify that no fields other than the expected fields for the given
>>    type were present, which you can usually do with
>>    Decoder.DisallowUnknownFields, but silently succeeds if one of the fields
>>    is valid for a different object type.
>>
>> I'm trying to do this as much with stdlib as possible. I've looked into
>> some other libraries that make heavy use of JSON decoding and have seen
>> both my above ideas, as well as just entirely custom Unmarshaller
>> implementations. Hopefully it doesn't come to that.
>>
>> Cheers,
>> Andrew
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CAPyCRsvvzzscpgfjj2vPQAi5_DVvrfhxLMu_OhuETzKAd7N1xQ%40mail.gmail.com
>> <https://groups.google.com/d/msgid/golang-nuts/CAPyCRsvvzzscpgfjj2vPQAi5_DVvrfhxLMu_OhuETzKAd7N1xQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CA%2Bv29Lue0t62BXrKLYG9CNcd7Bg6XRZJtH61MJG0NFm5jS5NuA%40mail.gmail.com.

Reply via email to