You might notice that an API in this style looks quite a bit like an API that conforms to the JSON:API spec. This is not a coincidence! But if you've worked with JSON:API, you can probably figure out why my preferred format differs in the ways that it does.
I think the intention behind JSON:API is excellent. As you can probably tell if you've read through all of this, I hold many of those intentions very close to my heart. Perhaps the most important thing is that your whole team agrees on the problems it's trying to solve, and in a lot of cases it's a huge achievement to just get everyone to convincingly declare, "Let's use JSON:API."
I was so excited when the first draft of the JSON:API spec was published. I was building an API with a big team at the time and I pushed really hard for us to use it. We built some generic client and server libraries in the languages we were using in-house and we started modeling.
The modeling was a really great process. What used to be blobs of data invented and owned by different teams were becoming discrete objects we could discuss and reason about.
Where things started to fall down was in the finer details of how that data gets turned into JSON. Different members of the team latched on to different details of the spec. Things like…
- When a relationship ought to include an
href
, - Or whether an attribute that was a big object—technically legal—was better served as a relationship,
- And if so, how that relationship's data should be persisted,
- And what that meant for the other metadata around that new resource,
- And what
POST
s andPUT
s should look like for this new network of data, - And how to generically support the
include
parameter for everything, - And so on.
The JSON:API spec tries to be a perfectly abstract representation of any arbitrary system that may be represented by JSON delivered over HTTP, and as a result I found that it is over-defined in some areas and under-defined in others. This leads to actual implementations making really curious choices. As is probably obvious by now, I think a more pragmatic approach is better.