How Granular Should You Design APIs?

One of the many things to take into account when building a great API is granularity. For more experienced developers, the concept of granularity is a given, but it may be a confusing concept for programmers new to API development.

In this short article, we’ll introduce you to the concept of API granularity with a helpful and ultra-flavorful analogy, comparing the pros and cons of fine- and coarse-grained APIs as we go. To close off, we’ll look at how you can determine the right level of granularity for your own APIs.

An Introduction to Granularity

First things first — what is granularity?

Granularity is the extent to which an API divides information among individual resources. It doesn’t actually refer to how much information an API exposes, but rather how many resources that information is spread across. With a fine-grained API, a consumer might have to make multiple, highly-specific requests to different endpoints in order to get the same amount of information as they would from a single call to a coarse-grained API.

To really solidify that idea, let’s look at an example. Imagine you’re building a social media platform and you want to expose basic user information — such as users’ names, hobbies, and friends — by means of an API. How would you implement this?

One approach is to allow developers to GET all of the user’s data at the /user/{userID} endpoint, which may return a response something like this:

{
"name" : "Thomas Bush" ,
"hobbies" : [ "cooking" , "swimming" ] ,
"friends" : [ "2" , "4" , "5" ]
}

With this approach, developers make just one request, but get all the user information they need — the user’s name, hobbies, and friends — in one response. This would be a coarse-grained resource.

An alternative is to split user information across separate /name/{userID}, /hobbies/{userID}, and /friends/{userID} endpoints. An example response from the /hobbies/{userID} endpoint would be:

{
"hobbies" : [ "cooking" , "swimming" ]
}

With this second approach, the developer has to make three separate requests — to the /name/{userID}, /hobbies/{userID}, and /friends/{userID} endpoints — just to get the same information as from a single call to the /user/{userID} we first presented. This, then, would be a fine-grained resource.

The question is: what’s better? An API with fine-grained resources or an API with coarse-grained resources?

Fine-Grained vs Coarse-Grained

There’s a case for both fine and coarse granularity in terms of API performance. With coarse-grained resources, developers need to make fewer calls to get the same amount of information, thereby reducing cumulative latency and speeding up implementations. However, with coarse-grained resources, you run the risk of giving consumers more information than they need, thereby using excess amounts of bandwidth.

The opposite is true for fine-grained resources. On the one hand, you’re not giving consumers more information than they need (thus saving bandwidth), but on the other hand, developers now need to make more calls to get the same amount of information (thus slowing down client implementations).

When it comes to performance, you will have to make a trade-off between fine and coarse granularity. How you make that trade-off will depend on how your API is used. For example, if your API mainly serves mobile users, you might want to lean towards finer-grained resources, which would minimize bandwidth usage. On the flip side, if your API provides real-time financial market data, you might want to lean towards coarser-grained resources, which would reduce the effects of latency.

The Pizza Factory

It’s not just a question of performance, though. Granularity can have a big impact on how developers interact with your API, and this is where I want to introduce a fantastic, pizza-based explanation of API granularity I saw on LinkedIn.

The analogy goes like this: suppose you provide pizza ingredients to a range of clients — pizza restaurants, amateur chefs, and hungry developers. If you were to provide a fine-grained service, you might offer flour, cheese, herbs, various sauce ingredients, and a selection of toppings. This would certainly attract pizza restaurants as clients.

If you wanted to take a slightly coarser approach, you could offer pre-made pizza dough, a ready tomato sauce, and some toppings. On the one hand, this means less freedom for your clients — since they can’t make the dough or source exactly as they want — but it also means less complexity. As a result, pizza restaurants might be less interested, but amateur chefs will be more interested!

However, hungry developers won’t want either of those. They’ll want a freshly-cooked pizza that’s ready to consume right out of the box! But of course, if you only sell cooked pizzas, neither pizza restaurants nor amateur chefs will be interested.

Are you selling the pizza ingredients or the whole pizza? API granularity will impact who your target developer is, and vice-versa.

I think this analogy does a great job of highlighting two crucial ideas:

  1. There’s a close relationship between granularity and business context
  2. Coarser granularity tends to mean less freedom, but also less complexity (which is why coarse grain resources need to be designed with extra concern for how they will ultimately be used)

In particular, it’s that first idea which is really important to bear in mind when finding the right granularity for your APIs: the correlation between granularity and business context. You can make an API a lot easier to work with by ensuring it exposes data (and functionality) correspondingly to some practical context.

This is where it’s really important to know who’s using your API and what for — so you can choose the right level of granularity for them, and so you can make sure coarser-grain resources actually correspond to their needs.

Final Thoughts

The idea of granularity really isn’t as difficult as it sounds. It’s a question of whether you’ll expose individual, fine-grained resources separately, or combine them to create a single, fuller resource. Choosing the right level of granularity is always going to be a performance trade-off, but it’s the relationship between granularity and business context which makes us lean towards the coarse side.