If you publish a RESTful API and there are situations when you need less (or more!) detail in the API responses from your API - then this post is for you. When I run into this with the teams I advise, the initial problem statement usually arrives more like "We need to move to GraphQL", but this is a solution, not a problem to solve. The problem usually turns out to be either or both of:
- the API responses are simply too large for some of the clients or uses cases, users need to select just the fields they want
- the API doesn't have enough information in the response payload for this client or use case, users need to choose to include nested data
GraphQL is one way to achieve these things, but this post is about the RESTful way to provide the right level of detail in an API response.
A little REST theory
A quick dive into the formal structure of REST will give the foundation we need to understand the options.
REST stands for REpresentational State Transfer; the idea is that we're presenting a way to transfer representations of resources. There are no rules anywhere that say you must or must not include particular data, or that you can only choose one representation (actually there are a whole load of rules that don't exist about REST, you don't have to expose your entire database structure ... I think this is another blog post so I'll save it for another day!).
We can use this concept of representations to provide a choice of formats to an API consumer.
Representations of resources
Let's get away from the theory and look at an (imaginary) example. It's really an API design choice whether I build my potions inventory API 1 to return something like this:
name: Luckyleaf Elixir effect: Temporarily enhances good fortune
Or if I define an interface that returns a lot more context:
name: Luckyleaf Elixir effect: Temporarily enhances good fortune ingredients: [Four-Leaf Clover, Whispering Willow Sap, Stardust] duration: 3 hours brewing_instructions: Steep the clover in whispering willow sap under starlight, sprinkle stardust at dawn, and recite a wish. side_effects: [Mild Overconfidence, Unexpected Coincidences] origin: First crafted by the renowned herbalist Fortuna Greenfingers to escape a series of unfortunate events.
Either of these representations might be useful, but in different contexts. RESTful services allow us to offer more than one representation of a resource at the same URL, and picking from a short list of options is simpler than figuring out what data structure you want and how to request that.
To implement this option, either keep it simple with a ?format=verbose parameter to switch between response types, or use an Accept header to allow the user to pick the media type they want (a good example of the Accept header approach is how it is used to offer patch/diff/sha/json responses in the GitHub API commits endpoint ).
GraphQL is not (always) the answer
GraphQL is a good option where the users' use cases are truly unknown, or data exploration is a feature. But otherwise I would recommend weighing up the options before setting on a whole API replacement programme because one endpoint is too verbose, or not verbose enough. We have established design practices that can help, and I hope the example in this post gave you some ideas.
[1] In the writers room for this post, meaning me and ChatGPT, I asked for some fun API example ideas, and then asked for an OpenAPI file to illustrate the concept. The result made me laugh, and if it would make you laugh too then you can find the Potions Inventory API on GitHub.