Best practices with REST APIs

We've already gone through some of the best practices when writing REST APIs, like using HTTP methods properly, or choosing the correct status code for your responses. We also described two of the most used authentication systems. But there is still a lot to learn about creating proper REST APIs. Remember that they are meant to be used by developers like yourself, so they will always be grateful if you do things properly, and make their lives easier. Ready?

Consistency in your endpoints

When deciding how to name your endpoints, try keeping them consistent. Even though you are free to choose, there is a set of spoken rules that will make your endpoints more intuitive and easy to understand. Let's list some of them:

  • For starters, an endpoint should point to a specific resource (for example, books or tweets), and you should make that clear in your endpoint. If you have an endpoint that returns the list of all books, do not name it /library, as it is not obvious what it will be returning. Instead, name it /books or /books/all.
  • The name of the resource can be either plural or singular, but make it consistent. If sometimes you use /books and sometimes /user, it might be confusing, and people will probably make mistakes. We personally prefer to use the plural form, but that is totally up to you.
  • When you want to retrieve a specific resource, do it by specifying the ID whenever possible. IDs must be unique in your system, and any other parameter might point to two different entities. Specify the ID next to the name of the resource, such as /books/249234-234-23-42.
  • If you can understand what an endpoint does by just the HTTP method, there is no need to add this information as part of the endpoint. For example, if you want to get a book, or you want to delete it, /books/249234-234-23-42 along with the HTTP methods GET and DELETE are more than enough. If it is not obvious, state it as a verb at the end of the endpoint, like /employee/9218379182/promote.

Document as much as you can

The title says everything. You are probably not going to be the one using the REST API, others will. Obviously, even if you design a very intuitive set of endpoints, developers will still need to know the whole set of available endpoints, what each of them does, what optional parameters are available, and so on.

Write as much documentation as possible, and keep it up to date. Take a look at other documented APIs to gather ideas on how to display the information. There are plenty of templates and tools that will help you deliver a well-presented documentation, but you are the one that has to be consistent and methodical. Developers have a special hate towards documenting anything, but we also like to find clear and beautifully presented documentation when we need to use someone else's APIs.

Filters and pagination

One of the common usages of an API is to list resources and filter them by some criteria. We already saw an example when we were building our own bookstore; we wanted to get the list of books that contained a certain string in their titles or authors.

Some developers try to have beautiful endpoints, which a priori is a good thing to do. Imagine that you want to filter just by title, you might end up having an endpoint like /books/title/<string>. We add also the ability to filter by author, and we now get two more endpoints: /books/title/<string>/author/<string> and /books/author/<string>. Now let's add the description too—do you see where we are going?

Even though some developers do not like to use query strings as arguments, there is nothing wrong with it. In fact, if you use them properly, you will end up with cleaner endpoints. You want to get books? Fine, just use /books, and add whichever filter you need using the query string.

Pagination occurs when you have way too many resources of the same type to retrieve all at once. You should think of pagination as another optional filter to be specified as a GET parameter. You should have pages with a default size, let's say 10 books, but it is a good idea to give the developers the ability to define their own size. In this case, developers can specify the length and the number of pages to retrieve.

API versioning

Your API is a reflection of what your application can do. Chances are that your code will evolve, improving the already existing features or adding new ones. Your API should be updated too, exposing those new features, updating existing endpoints, or even removing some of them.

Imagine now that someone else is using your REST API, and their whole website relies on it. If you change your existing endpoints, their website will stop working! They will not be happy at all, and will try to find someone else that can do what you were doing. Not a good scenario, but then, how do you improve your API?

The solution is to use versioning. When you release a new version of the API, do not nuke down the existing one; you should give some time to the users to upgrade their integrations. And how can two different versions of the API coexist? You already saw one of the options—the one that we recommend you: by specifying the version of the API to use as part of the endpoint. Do you remember the endpoint of the Twitter API /1.1/statuses/user_timeline.json? The 1.1 refers to the version that we want to use.

Using HTTP cache

If the main feature of REST APIs is that they make heavy use of HTTP, why not take advantage of HTTP cache? Well, there are actual reasons for not using it, but most of them are due to a lack of knowledge about using it properly. It is out of the scope of this book to explain every single detail of its implementation, but let's try to give a short introduction to the topic. Plenty of resources on the Internet can help you to understand the parts that you are more interested in.

HTTP responses can be divided as public and private. Public responses are shared between all users of the API, whereas the private ones are meant to be unique for each user. You can specify which type of response is yours using the Cache-Control header, allowing the response to be cached if the method of the request was a GET. This header can also expose the expiration of the cache, that is, you can specify the duration for which your response will remain the same, and thus, can be cached.

Other systems rely on generating a hash of the representation of a resource, and add it as the ETag (Entity tag) header in order to know if the resource has changed or not. In a similar way, you can set the Last-Modified header to let the client know when was the last time that the given resource changed. The idea behind those systems is to identify when the client already contains valid data. If so, the provider does not process the request, but returns an empty response with the status code 304 (not modified) instead. When the client gets that response, it uses its cached content.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.164.75