The Elements of APIs

Designing Data

Some of the choices I’ve listed so far may seem arbitrary, and they are! You and your team should make aesthetic changes if you want to, but I urge you to define them on a system level. If you can’t agree on something that is subjective, I recommend that you just do what I said, because it doesn’t matter and this way of doing things is already written down.

Once you’ve gotten the formats out of the way, you’re left with the hard part, which is also the fun part. It’s time to design your resources!

Resource design should be done carefully, deliberately, and with lots of input from everyone involved. This means the engineers writing the routes and the ones calling them, but it also means the visual designers who will create interfaces that are filled with these resources, and the product owners who will craft (or already have crafted) the business requirements that will be satisfied by these resources.

Remember that all of your business logic, 100% of the things a user of your system can do, must be defined in terms of the retrieval, creation, update, and deletion of resources.

Ideally you already have some rough user journeys or UI flows to reference here. If not, this is the time to create them. They don’t have to be final or polished; you and your team just need a shared understanding of what a user is going to do.

At every step of the journey, there is probably some data to show the user, and some data the user might send to you. Map every last shred of data to one attribute on one resource. If you’re building a web app, there ought to be one identifier that maps to the ID of one resource that can then be used to fetch everything else. For a blog post, your URL might be /articles/{id}. On the page might be a title, body, publish date, author name, author photo, and comments; comments might consist of a commenter name, commenter photo, body, and publish date.

A predictable choice here is that the ID in the URL corresponds to the ID of an Article resource. An Article has attributes for title, body, and publish date. An Article has relationships called author, which is one User resource; and comments, which is a collection of many Comment resources. A User has attributes for name and photo; a Comment has attributes for body and publish date, and an author relationship to a User.

Now we know that rendering this page requires a GET for an Article by ID, a GET for the Article’s comments relationship, and a series of GETs for Users, based on the author relationship of the Article and the author relationships of the Comments.

You may start to bristle at the number of HTTP requests you’re making here. During implementation, you may choose to introduce some mechanism for wrapping all of this up in fewer requests, perhaps by embedding the Users in the resources they’ve authored, or adding a filter option for GET /users that accepts a series of IDs, or some other technique. I advise you to avoid doing this kind of thinking in the design phase. Get your resource definitions right first.