Hacker News new | ask | show | jobs
by golergka 2070 days ago
> XYZ’s protocol is not just based on JSON, but it’s based on a particular technique known as polymorphic JSON. In this, a single field could have a different data type in different circumstances. For example, the resources field can be an array when requesting a single access token, or it can be an object when requesting multiple named access tokens. The difference in type indicates a difference in processing from the server. Within the resources array, each element can be either an object, representing a rich resource request description, or a string, representing a resource handle (scope).

This is horrible.

2 comments

This is definitely not a protocol dreamed up by, say, Java developers.

Obviously it's doable in Java, but I'm hard-pressed to imagine a Java developer would think of such a thing.

The only time I've ever encountered an API that used it extensively, it was done by a company that does all their implementation in Java.

My best guess at what happened, based on the shape of the API, is that they implemented it by taking their pre-existing domain model, which had a fairly deep subclassing hierarchy, liberally sprinkled some annotations from com.fasterxml.jackson.annotation, and dumped the result straight onto the wire.

You could absolutely do an object-oriented codebase where two different subclasses have fields with the same name and different types, and, depending on how you structure your code, it might not be too painful. And it's fairly easy to imagine someone serializing a structure like that to JSON without ever meditating on the fact that JSON won't retain the all the type information.

Ironically, the end result was an API that is nigh-impossible to consume from Java. I ended up writing a façade in Python.

I've also seen little bits of this happen in the internal APIs at my current company. Also a Java shop, also a result of trying to directly connect an internal object model to the API. I've never seen it done in an API implemented in a dynamic or functional language.

I hadn't considered the one-way nature of dumping Java classes to JSON.

Mainly because I work with classes that are serialized both to and from JSON, rather than having Jackson annotations added much later.

I can see it now. Horrifying! I'm sorry for your troubles.

My take-away is this: Protocols should always be defined independently of any existing code.

The code-first approach only works well when you're doing something self-contained. Which, an API, almost by definition, is not.

I generally try to design APIs from a consumer perspective, and then usually I end up with something RESTful. Let the server do whatever it has to do, you know?
This is a few magnitude even more infuriating than a spec I have to work with at work, where some keys are required to be URI...
I work in Typescript, which is arguably the best mainstream language suited to type such things, and still. This is insane.
Lovely - I can't wait to see how horrible something like that is to implement in a language like Go.
You have to implement UnmarshalJSON. Between each attempt to deserialize into a possible struct, be careful to return on errors that are not JSON serialisation errors (for example caused by reading from the underlying Reader, etc.)

It's ugly and verbose but there is no need to use empty interface.

Sounds like a golang problem. Rust can easily handle it with union types from what I have seen.
I hope you enjoy working with interface{}

_sigh_

interface{} to the rescue