Building good APIs

Building good APIs

Knowing how is the architect of a REST API is important. I could talk about this in this article, but my friend Bruno Oliveira already has a good article about this. So I advise you to read first such article and return to here. The link is https://www.dhirubhai.net/pulse/do-all-restful-services-really-live-up-its-adjective-bruno-oliveira/.

But understanding how the REST API works isn't enough to build good APIs. Sometimes, simple mistakes take off the quality of an API. With this, use and maintainability get bad.

To avoid this situation, this article shows some good practices to help us build better APIs. All developers should use these simple practices, but unfortunately, they don't. Before we start, please listen to the next song, which shows in a relaxed way, the topics of this article: https://www.youtube.com/watch?v=nSKp2StlS6s.

Now, let's start... :)

Use HTTP methods the right way

There are a few methods in the HTTP protocol, but let's focus on the most used or which should be: GET, POST, PUT, DELETE and PATCH.

It's very common to see applications using only GET or POST requests to do all operations. Although it works, the concept of a REST API doesn't agree with this. Each operation has its own HTTP method. Thus, we should do like this:

  • GET: use when you need to get data or resources from the server;
  • POST: use when you want to create a new entity on the server;
  • PUT: use when you want to change all values of an entity on the server. In other words, you want to update the whole entity;
  • DELETE: use when you want to remove an entity on the server;
  • PATCH: use when you want to change some values of an entity on the server. In other words, you only want to update some values of an entity.

Though this sounds like obvious, it's not. As I said before, using the methods in the wrong way makes the API non-fluent and difficult to understand. Many times to solve this, another bad practice is done and I'll talk about it in the next tip.

Create URIs the right way

When we don't use the HTTP methods in the right way, we're forced to use another way to say what such endpoint does. This way, the URIs become responsible to do this.

However, to do this we're obliged to use verbs on the URIs and this is a bad practice. When we do this, the concept of REST API is not applied: URI must show the manipulated resource, not the operation.

But if we're using the right HTTP methods, we're able to create good URIs. Thus, we should follow the tips below:

  • URIs must not end with a slash (/):

Write

GET: https://some.company.api.com/products
        

Instead of

GET: https://some.company.api.com/products/
        

  • Use spinal case to create URIs

To write in spinal case, use hyphen (-) to separate the words.

Write

GET: https://some.company.api.com/company-document
        

Instead of

GET: https://some.company.api.com/companyDocument
GET: https://some.company.api.com/company_document
        

  • Use lowercase letters

Write

GET: https://some.company.api.com/reform-budget-room
        

Instead of

GET: https://Some.Company.API.Com/Reform-Budget-Room
        

  • Use singular nouns to identify an exactly resouce

The next URI creates a new car entity on the server. The values will be sent in the request body.

POST: https://some.company.api.com/car
        

  • Use plural nouns to identify a collection of resouces

The next URI gets a collection of existing cars

GET: https://some.company.api.com/cars
        

  • Use path param for a specific resource and request params to additional filters information

The next URI gets the student with id 45698.

GET: https://some.company.api.com/student/45698
        

The next URI gets students with the name “Thiago” who are 41 years old.

GET: https://some.company.api.com/students?name=thiago&age=41
        

  • If you need, mix plural and singular nouns with param

The next URI gets the player with t-shirt 10 of the team Borussia Dortmund of the bundesliga of the championships collection


GET: https://api.soccer.org/championships/{liga}/teams/{team}/player/{id}


GET: https://api.soccer.org/championships/bundesliga/teams/borussia-dortmund/player/10
        

There are some others tips in the Mark's book. See it the Reference's section.

Use HTTP codes the right way

There are many HTTP codes and they are responsible for indicating the results of operations. To facilitate its use and understanding, there are groups for each type of result:

  • Informational responses (100–199)
  • Successful responses (200–299)
  • Redirection messages (300–399)
  • Client error responses (400–499)
  • Server error responses (500–599)

Unfortunately, it's common to see applications using usually 3 codes: 200, 404 and 500. It's a terrible way to report so many types of results. To solve this, we focused on the main groups: success, client and server error. Understanding the concept of each code helps us to provide better results and create consistent APIs. Thus, a strong contract between client and server makes both more reliable. The web server can return the underlined codes automatically, but we can use them if we need. The developers use the others more.

  • 200 OK

We should use this code when the request is successful according to the following situations:

- GET request fetched and resource transmitted in the message body;

- PUT, PATCH or POST update or create an entity. If we need, the entity can be transmitted in the message body;

- DELETE removes an entity and no message must be transmitted.

  • 201 Created

We should use it with a newly created entity. This is typically the response for POST requests and you don't need to return the new entity.

  • 202 Accepted

We should use this code with successful requests but not yet processed. It's useful when the data transmitted will be processed in a batch way in another moment.

  • 204 No Content

We should use it with a succeeded request for GET, PUT, POST or DELETE operations, but we don't need or can't return a response with a body. The body must be empty.

  • 400 Bad Request

We see it when the request isn't correct by the format, values or another's errors.

  • 401 Unauthorized

We should return this code when the request doesn't contain the required username and password to access the API.

  • 403 Forbidden

We can see it when the request contains the required username and password, but access rights don't allow the request's execution. Maybe, some server configuration must be done to permit the access.

  • 404 Not Found

This is the most famous HTTP code and we use or use it when we want to inform that the desired resource doesn't exist.

  • 405 Method Not Allowed

This code means that the request sends the wrong method to an API. For example, the API supports the PUT method but receives a POST. It's possible to return a hint in the body with the correct method.

  • 406 Not Acceptable

We see this code when the request contains a content response format that the server can't return. For example, the API supports JSON returns, but the request wanted an XML.

  • 408 Request Timeout

This code is seen when the server is busy and cannot respond to a request within the time that the server was prepared to wait.

  • 409 Conflict

We should use it to inform that the request(POST, PUT, PATCH or DELETE) can't execute, because will create an inconsistent state in the resource/entity.

  • 415 Unsupported Media Type

This is the opposite of the 406 code. The client now sends a request content format that the server doesn't recognize. Thus, the request cannot be processed. For example, the API accepts JSON requests, but the request sends an XML.

  • 422 Unprocessable Entity

We should use this code when the incoming request is not completed. The content and format are correct, but some business logic doesn't allow it to finish successfully.

  • 500 Internal Server Error

This code means that some unexpected error occurred on the server. The problem is not with the request or response, but with the server. These are usually runtime errors like nullpointer, database shutdown, and so on.

  • 503 Service Unavailable

The server cannot respond to the request now. Maybe it is busy or is only temporarily not processing the request, because of time or maintenance.

There are some others codes. If you need a specific code for your needs, look for them in the References section, second and third links.

Version your API

It's a good idea to version APIs. Thus, we avoid breaking clients. Remember many times the same API can be used for many clients. So, updates may introduce unexpected errors for some clients. If a new or an old client needs new data(values, format, etc), it's best a new version for him.?

The most used way to version an API is "Path Version". In this API version type, the URI shows the API version. For example:

https://my.api.com/do-something


https://my.api.com/v1/do-something


https://my.api.com/v2/do-something
        

In the previous URLs, the first URL is the original version. The second is the first version for a specific client. The third URL it's the second version to serve another client.

There are other ways to version an API like "Query String", "Subdomain" or "Headers". But as I said, "Path Version" is the most used. If you prefer one of the other ways, google it. There are lots of examples of them.

Document your API

Documenting software is very important and an API is no different. When we do this, a complete API view becomes public and we create a communication contract. Thus, we improved the use of this API.

This documentation, helps clients understand how to send requests, which type of return are available, how to handle returns and other important informations. Knowing this, helps us to build better clients for APIs and in the end better softwares.

There are some frameworks to helps us to document APIs. The most famous is Swagger, but another like API Blueprint and RAML can also be used. Choice one, google it and you'll build a good APIs.

Final words

This article showed some best practices that help us build better APIs. We noticed that they are all simple to do, but unfortunately sometimes they are not done. It's good practice to always care about them when we're building an API. That way, our APIs will be better. Think about it! Bye. ;)

References

MASSé, Mark.?REST API Design Rulebook: Designing Consistent RESTful Web Service Interfaces. O'Reilly Media, Inc.", 2011.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9

https://swagger.io/docs/

https://semver.org/

https://apiblueprint.org/

https://raml.org/

Very nice! A pragmatic and clear view of the main good practices for building better APIs :)

Karol Guerini

Analista de testes | QA Automation Mobile | Testes de Software | Testes Web | Testes Mobile | Testes de API |

2 年

要查看或添加评论,请登录

社区洞察

其他会员也浏览了