Right-Size Your RESTful API: More Flexibility Without GraphQL

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

If you have a RESTful-ish or HTTP API that is returning too many fields, or too few, then consider if you can iterate on the solution that is already in place before replacing it with a different approach entirely. GraphQL is good for plenty of use cases, but I usually try to start by looking at using more representations in REST because:
– plain HTTP APIs are more widely understood by both users and tools
– offering a small list of formats is simpler to understand for users to just pick from the menu, and as a provider it is easier to evolve those formats moving forward
– optimising a small number of known options, such as returning just the basics of an item, or returning it and a bunch of related data in the response, is easier to optimise and crucially for APIs running at scale it can be cached (one of the main benefits of REST!)
– it’s less disruptive to extend an existing API than to introduce a new technology and support two APIs

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.


Also published on Medium.

2 thoughts on “Right-Size Your RESTful API: More Flexibility Without GraphQL

    • Thanks for mentioning this! Might be interesting for people starting from the other end of the process that already have a GraphQL API and want something more RESTful.

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

This site uses Akismet to reduce spam. Learn how your comment data is processed.