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 and...@burian.ca 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/b6599706-e531-4965-879e-7c6e0f97eaebn%40googlegroups.com.