What Is a Restful API?
In this post I will explain what a RESTful API is but first let’s see what HTTP verbs are.
Briefly about HTTP Verbs
There are several HTTP verbs which are basically different types of HTTP messages, intended for different use cases. The ones that we are interested in are:
- GET – retrieve data at the specified resource
- POST – send some data (usually in JSON format) to create a resource
- PUT – send some data to update a resource
- DELETE – delete a specified resource
Here are examples of GET and POST requests. Note that the GET request does not have a body whereas the POST request does. POST’s body carries information about the movie being created.
Here are some examples of the requests mentioned above:
GET
POST
PUT
DELETE
REST – Individual Items
When working on a project’s backend, chances are that you will have to expose a web API that the clients (mobile app or a website front-end) can use. There are several API design styles, but REST is the one that’s more commonly used. The key idea of REST is that the architecture is centered around resources, not actions. What do I mean by this?
Suppose that we have an API that allows to manage Movies and has the following endpoints:
- http://moviestore123.com/getMovie
- http://moviestore123.com/addMovie
- http://moviestore123.com/updateMovie
- http://moviestore123.com/deleteMovie
As we can see, in this design style, actions are emphasized rather than resources, which contradicts the REST style. And now take a look at something like this:
- http://moviestore123.com/movies/1 (GET)
- http://moviestore123.com/movies/1 (PUT)
- http://moviestore123.com/movies/1 (DELETE)
Here we have an endpoint /movies and we also have /movies/1 which is a movie with ID 1. This is the RESTful way of designing an API. The architecture is centered around a resource (movies) and we use HTTP verbs to perform actions on the resource:
- http://moviestore123.com/movies/1 (GET) should return a JSON or XML representation of a movie with ID 1.
- http://moviestore123.com/movies/1 (PUT) should update the movie with ID 1. We would have to provide the updated information in the body of the request.
- http://moviestore123.com/movies/1 (DELETE) should delete the movie with ID 1 from the database.
REST – Collections
Up until now, we focused on dealing with individual items (a single movie with ID 1). But what if a client needs to fetch a collection of items? Say we want our mobile app to display a list of all available movies. We could achieve this with the following endpoint and verbs:
- http://moviestore123.com/movies (GET)
- http://moviestore123.com/movies (POST)
- http://moviestore123.com/movies (PUT)
- http://moviestore123.com/movies (DELETE)
In the previous section, we dealt with the endpoints of format http://moviestore123.com/movies/1 but now we go a level up. We apply the HTTP verbs to the collection of objects which is represented by /movies :
-
- http://moviestore123.com/movies
(GET) should return a representation of a collection of movies. Pagination deals with the exact amount of individual movies returned. - http://moviestore123.com/movies
(POST) should create a new individual movie within the collection. Note that in the previous section, we did not use the POST verb but now we do. This is because we considered individual movies in the previous section. It would be impossible to add a new movie to the ID of an existing one. Also note that we will have to provide the
information about the movie to be created in the HTTP request’s body. - http://moviestore123.com/movies
(PUT) should perform a bulk update of the movies - http://moviestore123.com/movies/1
(DELETE) should remove all movies from the database
- http://moviestore123.com/movies
REST – Complex Relationships
Now suppose that we also want to use our API to provide information about the cast of the movies. Let’s see the endpoints that we can use to achieve this functionality:
- http://moviestore123.com/movies/1/actors (GET, POST, PUT, DELETE) – access the collection of actors that performed in an individual movie
- http://moviestore123.com/movies/1/actors/2 (GET, PUT, DELETE) – access the individual actors from an individual movie
So basically we just added another collection and another individual item to the URI. Now the general format of the endpoint is collection1/id1/collection2/id2. But what if each actor has information about the movie genres that he/she performs in? Would we construct an endpoint of this format: /movies/1/actors/2/genres/3 ? Although that is technically possible, this is not the recommended design. What we should rather do is split this up into two separate endpoints like:
/movies/1/actors/ – to find all actors associated with an individual movie
and then
/actors/2/genres – to get all genres associated with a particular actor. If we have actors with IDs 2 and 3 that we need the genres for, we would make two requests like /actors/2/genres, then /actors/3/genres
API Versioning
Since the API is likely going to change over time, it is wise to version it appropriately so that the old and new versions can coexist. We can change our endpoints to look like this:
http://moviestore123.com/v1/movies
When a new version of the API is ready, we will simply serve it at
http://moviestore123.com/v2/movies
Because of this, we will not break any client code that is using the old API and at the same time we enable new applications to use the new API.
Thank you for reading this article and if you have any questions, please let me know in the comments! I plan to write another post that will go into HATEOAS, pagination, filtering, sorting and searching so stay tuned!