>I intensely dislike the need to define a rigid type to serialize / deserialize.
You can deserialize to a map, without having to define rigid types upfront. But for me, it's more painful to use, because instead of writing something simple like "person.Address.City" with "rigid types", I have to retrieve values by key and cast them to target types.
But pretty much all JSON I have dealt with had an implicit schema, so I see no problem with defining a schema using Go's type system. For me, it's a plus, and defining a type takes, like, 30 seconds? There's also the handy json.RawMessage which you can use to skip certain parts, or defer parsing to a later time.
>And go's libraries and syntax for dealing with dynamic json are pretty painful.
I don't remember having to deal with "dynamic JSON" in an API, can you give an example?
The problem with the typed interfaces are the many cases where the JSON isn't strongly structured, so you end up jumping through all sorts of hoops to make it work, or using a sub-par API like you mentioned, and casting everywhere.
Maybe it's just unavoidable with strong typing, I've had pleasant experiences with C# dynamics with JSON data, but nothing is as easy to me as "let thing = JSON.parse(stringstuff)" and then being able to just do "thing.?someprop" for consumption.
Sure, it only takes 30 secs to add a new type, but the issue is that it has cascading effects. Then build and deploy, etc... whereas with Node, I can just do runtime checks and fail softly.
Sorry, I don't mean to resurrect the old strong vs dynamic typing debate, they each have their use - but for REST APIs specifically I find JSON + dynamic types to be a lot more effective.
And go's libraries and syntax for dealing with dynamic json are pretty painful.