Rest – How to decide the granularity for RESTful APIs

api-designhttpooadrestsolid

Most of us know SOLID, and over the years have understood how useful it can get when we need to change.

Based on S & I parts of SOLID and from experience I used to design my HTTP RESTful services as fine-grained as I could. For example, in a simple contacts management system, I would create and expose these endpoints:

  • createContact?firstName=x&lastName=y
  • addPhoneToContact?contactId=x&phone=y
  • addEmailToContact?contactId=x&email=y
  • associateContactWithGroup?contactId=x&groupId=y
  • removePhoneFromContact?contactId=x&phoneId=y
  • updateContactName?contactId=x&firstName=y&lastName=z

However, recently we were arguing over the granularity of our RESETful services, and a colleague proposed that we see Google's Contact as a sample and model.

To my surprise, I saw that they update contact in a very complex and coarse-grained manner, in one simple API.

We all have to admit that Google is the Internet's giant, and they don't do things without knowing what their doing.

If this was an arbitrary website, I wouldn't even consider them, and would probably argue that their developers are not familiar with the concept of breaking things down (divide and conquer/analysis/WBS/SOLID/…). But Google, is totally different.

Now I'm stuck at why they've done so, and which approach is more maintainable and better to create APIs. One big single API that updates/creates a complex model, or many small APIs that update/create small parts of that model.

This is a challenge for shopping carts, for contacts, for educational course management, for accounting articles and almost many more cases.

I know this might be subjective, but I'm searching to find objective reasons behind each approach, so that we can decide with more knowledge.

Best Answer

This borders on a religious answer, but....

The examples provided in the question are not RESTful, to me. createContact is a verb, not a noun, and does not specify the request type. The REST paradigm would suggest:

POST /contact - data={firstname: 'blah', lastname: 'blah'}

The removePhoneFromContact?contactId=x&phoneId=y would become:

DELETE /contact/x/phone/y or DELETE /phone/y if the phoneId is globally unique

Similarly, the edit operations could be done by a PUT or a PATCH. The PATCH would be useful where you only want to change one field, and you aren't required to send the full resource. Things like etags and last-modified headers are used to ensure consistency.

Google also has many considerations that we Common Folk do not. The savings of a few percentage points in network usage may be far more important to them than the ease of understanding of an API.

Related Topic