Hi!
It's not possible to decode this data without scanning it twice. It's a
flawed design where someone has chosen to make that restriction.
programming language doesn't matter.
The only way to avoid parsing it twice is to decode to a map[string]any and
then use that as-is. Which I suppose you might end up doing in some
languages, but not in Go, for practical reasons.
I'd go with the first option, it's the easier one. However, if there's a
JSON schema, you should probably also consider using a compiler such as
quicktype.
You'll notice it will merge all the fields into a single struct and use
pointers for all optional field. Not great from a Go coding point of view
but OTOH by compiling the schema you save a lot of time not writing the
structs manually and also not needing to keep up with future schema
changes, if they're frequent. To easily assign to the pointer fields I
added a func newval[T any](v T) { return &v } to my package.
Regards,
Per Johansson
On Monday, December 26, 2022 at 7:04:41 PM UTC+1 [email protected] 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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/b6599706-e531-4965-879e-7c6e0f97eaebn%40googlegroups.com.