Creating an API that’s design is readable, sustainable and scalable can be challenging. This short blog post looks at creating a developer friendly, informative and resource centric API design.
When building applications it is important to get the right URL design for two primary reasons:
- As you build a portfolio of applications, you will depend on API-first connectivity to integrate each application. The consumption of these APIs should be consistent and ultimately straightforward - regardless of the complexity of source or target system.
- If you want to grow your product, or solution, into a platform, you will want third-party developers to integrate with, and enrich, your ecosystem. A well designed, resourceful API enables developers to understand and consume your interface with little effort.
But it goes beyond consumption. As your applications grow, your API design must be sustainable and scalable. Not in terms of performance, but from the perspective of developer experience. Your APIs should be self-defining, readable and above all understandable.
Anybody who has used a MVC pattern “out-of-the-box” will have seen and probably written, APIs with a fixed-tier URL path. For example, look at the following resource hierarchy.
This might translate into the following fixed-tier API paths…
For a simple data hierarchy, this works okay. Although it is not particularly readable. As you can see, fixed-tier paths can only scale so far. With a resource hierarchy greater than two-tiers, the design is flawed.
We need to better design our APIs.
The following section explains the process and rules I use for API design. Yours could, and probably should, differ to complement your requirements. Use the section below as a working example.
Think about the data, information and processes you want to expose and consume before building your API. Understand the hierarchy of resources and the actions you want to invoke at each level of the hierarchy. Will others consume your APIs? And if so, what should their experience be?
Take the following, three-tier resource hierarchy.
Using the same fixed-tier paths as above, we can’t represent three-tiers. It would end up looking something like this.
Instead, if we followed the hierarchy, we could write the path like this.
Reserve path segments for entity names and their unique identifiers.
When we combine this pattern, with RESTful HTTP verbs (GET, POST, PUT, PATCH and DELETE) we can begin to represent actions at each level of the hierarchy.
GET /api/customers POST /api/customers GET /api/customers/[customerId] DELETE /api/customers/[customerId] GET /api/customers/[customerId]/orders PUT /api/customers/[customerId]/orders/[orderId] POST /api/customers/[customerId]/orders/[orderId]/products
Finally, as path segments are reserved for entity names and unique IDs, we can use the URL query string to query our GET requests. Continuing the example above, this is how we might query our customers:
But we wouldn’t query our customers like this:
Hopefully you have found this post useful and you have been able to take something away to improve your API design.