This content originally appeared on Level Up Coding - Medium and was authored by Daniel Pericich
Imagine you are headed to work, ready to face another stressful day at the office. The subway was running late, one of your fellow passengers spilled breakfast salsa on your shirt, but you’re still on time for your morning standup. As you approach the front door of your office building you swipe your badge, but do not hear the familiar click of the door unlocking. You swipe a few more times and curse everything for your badge not interfacing with and unlocking the door.
Take this frustration of changing expectations and imagine your customers or clients trying to get bank information, log into their social media or watch a funny cat clip, but be met with a 404. It’s frustrating, and the variability of resource delivery will likely cost you clients and potentially your business.
People don’t like variable outcomes. They like consistency, as boring as it may seem. As software engineers, it is our job to create systems and interfaces that are predictable, fast and flexible so that we can meet the needs of evolving user expectations. How do we do this with API design?
Flexible API Endpoints
A key staple of a good API is consistency. A developer should be able to read the docs, identify a URI and then add an HTTP call to retrieve the resource for their app. If this process is done correctly, they should never have to touch this code again.
However, this is not always the case. Anyone with business or software engineering experience knows that business team goals change rapidly. In order to accommodate a growing set of requests to route, fulfill and return, we need to have flexible endpoints for our users to hit. We need a set of predictable and sensical URIs that communicate the reason of our endpoints to our users.
What is a URI? URI stands for Unique Resource Identifier. These are the endpoints or routes that a user integrates into their API calls to be able to get back a record (member), set of records (collection), or do work on a piece of data. URIs are made of resource names that point to a model (usually denoted as plural of the resource name) and an optional id which will point to the exact resource or record that you want. A URI may look like this:
‘/orders/15’
Which points to the collection of order records, and from the collection gets the 15th order record. URIs can be more complex such as:
‘/orders/15/customers’
Which will return the customer record for the 15th order in our database. It may seem to make sense to chain on multiple ids and model relationships to get to a resource with a single URI. See below:
‘customers/3/orders/16/order-items/2’
This URI points to the 3rd customer’s 16th order and the 2nd order item in that order. It’s great to be able thread directly to a product so quickly, however having a long string of relations and resource ids makes our API inflexible and more likely to break over time. This leads us to a key rule for good API development: each URI should have only one resource id.
One resource one ID
Why is this a good rule? The short answer is your app can stay simple and dumb. The previous URI requires your user to understand your database relations to use the API and create a relational structure that is brittle if we decide to rename or move resources.
In order to make the previous call we have to know the exact member values for the customer, order and order-item as well as their relation. If instead we break up this call into 3 calls:
‘customers/3/orders’
To retrieve all of the customer’s orders. Then:
‘orders/16/order-items`
Which we get by selecting one of the orders from the collection returned a step before. With this we can finally make a call to get:
‘order-items/2’
This gives us the second order-item. There are three calls here instead of one. Why would we structure our API like this? We do this because these calls are short and specific and do not create redundant URIs in order to retrieve resources.
Yes, the longer route works, but that URI is not reusable and takes a lot of bandwidth to understand. On top of this, there is no good way to build a user interface based off the long route. How is a user supposed to know that they want the second order item from their sixteenth order?
If you want to allow a user an easy way to find their order items from certain orders a better way to design the API would be to start with a simple URI based on the customer:
‘customers/3/orders’
Which will return all the orders for you to have for the user to choose from. Say they want to select the 16th order, you can have a link for the 16th order in your collection results from the previous order. The URI for this would be:
‘orders/16/order-items’
Again, this simple URI allows the user to now see all of the order items for their 16th order. If they want to see a show page instead of an index page for a specific item, you can use the order-item id of 2 to create a URI to the show page. It would look like this:
‘order-items/2’
All of these URIs are kept simple as we are filtering down on specific resources with URIs generated from our last operation. At the same time we are filtering, we are not relying on knowing any more information than a single resource id to get the next set of resources. They are short, simple and independent of other calls that may precede them.
Just because you should keep your URI’s simple (one resource, one id), doesn’t mean that you can’t make more complex queries. Because REST APIs are built on top of HTTPS, it is important to leverage query, sort and filter query params to best retrieve and format your users’ requested data.
Conclusion
There is so much to learn about designing an API that is predictable and consistent, but flexible and able to changes. Check out the link in my notes section if you’d like to learn more about API design!
Notes
https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design
Building Great APIs: One URI One ID was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Daniel Pericich
Daniel Pericich | Sciencx (2022-04-01T13:23:29+00:00) Building Great APIs: One URI One ID. Retrieved from https://www.scien.cx/2022/04/01/building-great-apis-one-uri-one-id/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.