Before we dive into how to design a REST API, let’s just briefly get on the same page on what a REST API is.
A REST API is an architectural style proposed by a guy named Roy Fielding in 2000. Since REST is an architecture, there is no set standard for how to design a “REST API”. Fielding specified a set of constraints that a REST API should follow and these are the only ones we should adhere to.
I’ve already mentioned one of the main constraints for a REST API in my previous post, a uniform interface. This means a client and a server should be able to evolve independently since the interface won’t change.
6 Alternatives to the Yahoo Finance API | Data Driven Investor
The Yahoo Finance API has long been a reliable tool for many of the data-driven investors. Many have relied on their…
Another important constraint in REST is that the interface must be stateless, so each request must contain all the information necessary to understand the request.
Caching is also a big deal in REST, as Fielding put it in his paper: “The most effective architecture styles for a network-based application are that can effectively minimize the use of the network”
Then there are also constraints on the interface interactions:
- Identification of interfaces
- Manipulation of resources through representations
- Self-descriptive methods
- Hypermedia as the engine of application state (HATEOAS). This one is mostly ignored because it’s difficult to maintain and often not useful in practice.
The goal of REST is to hide behaviour behind entities, so the server is free to implement whatever behaviour it wants without worrying about the client.
There are many more things to cover for REST APIs, but there are amazing resources out there for the more theoretical stuff. I’ll link to some at the bottom of this post and then we’ll move on to how to design a REST API with the above constraints in mind.
Since REST is more a set of principles than an actual recipe to build APIs, the term RESTful APIs have been coined to signify API that uses REST principles but also uses more technologies on top of it.
Designing an API
The API’s job is to make the application developer as successful as possible — API Design: The Missing Link, Apigee.
The most important thing to think about when building an API is the user. This user will most likely be a fellow developer, so you should build your API with that in mind.
Let’s say we have Alice, a front end developer who wants to build a nice UI to display your data. What would make Alices life easier when she is building her application? What format would she want her data in, how would she want to send requests and what would be easiest for her if you update to a new version?
These are all things you should consider before designing your API. So using some obscure data format to deliver data is perhaps not the best idea even if you would have fun implementing it.
In the previous article, I introduced the to-do list example. Now it is time to expand upon it. Say we want to create an API for some of the numerous to-do list applications being created during tutorials.
Here are the requirements for the API:
- Users can have todo lists
- A user can do CRUD operations on their todo lists and todos
- Users can share todo lists with one another
Since our API users will most likely be new developers, this API should be simple and intuitive to use. Which is why a REST API is a great place to start. No state to keep track of and uniform interface.
So our goal is to build a simple consistent API that is easy to understand and use.
REST is designed on top of HTTP, so if we stick to the HTTP protocol, we’re already well into building a REST API. So for requests, we should use GET, POST, PUT/PATCH and DELETE messages instead of
REST hides behaviour behind resources, so we don’t want to create endpoints that specify behaviour. Instead, we send different HTTP requests to the same endpoint:
There is no rule about naming, but the recommended standard is to use plural versions of resources. Whether you choose plural or singular doesn’t really matter, just keep it consistent.
Concrete naming is better than abstract naming.
todo-resource any day.
We should also specify what response code these requests can get. Again the default HTTP response codes will get you far.
GET /todo-lists - 200 OK, 404 Not found
POST /todo-lists - 201 Created, 400 Bad Request
PUT /todo-lists - 200 OK, 400 Bad Request
DELETE /todo-lists - 200 OK, 400 Bad Request
Then you can always include more descriptive error messages, but again there are no rules. You should specify the outcome of the request though. Otherwise, the user has no idea that the operation succeeded.
POST /todo-lists 200 OK
POST /todo-lists 400 Bad Request
"status": "400 Bad request",
"message": "Request must specify an owner"
For resources that are linked to one another, there are multiple ways of querying that. One is not necessarily better than the other
Just remember to stay consistent, if you offer one type, you should offer it for all your resources. The idea is that a developer should be able to implement your API with a minimum amount of documentation.
This one is hard to get right. There is a lot of discussions because on one hand an id like
friday-todo reads nicer and is easier to remember than
1234567 , but
1234567 is more permanent. There is a really interesting post about it here. Apigee suggests offering both, a permalink that looks like
1234567 and a name that looks like
friday-todo so you always have the same identifier, but also a name that is easy to remember when searching.
One thing that is considered good practice is to include a link to associated resources, so the user won’t have to extract it.
"name": "Pick up keys"
How your response body should look will be very dependent on the data you offer. One general rule to remember is; respect the JSON properties. They should not describe individual resources but should be generic to the resource.
So, in our todo list example.
If you want to be really cool, you should consider offering a query parameter for partial responses. This is a response where the user can specify which fields the user wants and the response will only contain those fields. Again, be consistent, if you offer it for one, you should offer it for all.
GET /todo-lists/<id>?fields="name, owner, createdDate"
A REST API only requires the following specification:
- A small set of well-known URLs
- The data model of each resource
- Which HTTP features are implemented
- Optionally some query syntax
If you need more than this you’re probably venturing beyond REST. It is not necessarily a bad thing but threads carefully.
I’ll end on a thought-provoking quote from Apigee. Something worth keeping in mind when designing an API.
“A significant part of the value of basing your API design on HTTP and REST comes from the uniformity that it brings to your API. In essence, when you use HTTP natively, you don’t need to invent an API at all — HTTP provides the API, and you just define the data in your resources.”
Thank you for reading, I hope you found it helpful! Let me know what you think, I am still learning myself and would love to know about your experiences. The full specification for the todo API can be found here and in the next post, we’ll start building it.
← Previous post: What is an API?
Next post: The basics of building a RESTful API →
API design: The missing link — Ebook by Apigee