In my work, I often come across various new concepts, ideologies and projects. Mainly due to the fact that I participate in the development of various large projects, in each of which I meet something new. Today I want to talk about my experience with the REST API. The ideology that I once had a chance to apply when developing one social network.
Much has already been written about this, and yet something complete, allowing me to find all the details I need in one place, when I first started doing this, I did not meet in the Russian-language edition. I will try to collect what I managed to figure out through trial, error and constant searches in working with various projects. So let's get started!
I want to immediately make a reservation: REST for me is, first of all, an ideology, to which I am anxious and tender. And, if someone is not ready to accept it for what it is - you should not read further this article. A programmer always has a lot of useful things to do, until he comes to understand the need to write recognizable interfaces and hide behind their simplicity the logic of applications of any complexity ...
')
I must immediately stipulate that I am a programmer, not a writer, and this is my first article. It may have turned out dry, but we are all techies here, I hope it will be interesting. In the article I will describe my experience with the REST API. I will try to make the article universal, so that according to my article this ideology can be applied to any Internet project.
Now let's get in order.
REST (Representational State Transfer - representative state transfer).Roy Fielding - described an approach called REST, back in 2000, this approach formed the basis of the well-known HTTP protocol. There are two types of writing for this architectural programming style: REST and RESTful, there are no differences in the meanings of these terms, just RESTful is an adjective from REST, that is, RESTful API is an API that complies with REST principles (I apologize to those who knew , but such questions are asked often enough).
REST (Representational State Transfer - representative state transfer).REST API structure
1. Client-server architecture
2. Stateless server
3. Cacheability
4. Multi-layer structure
5. Single interface
- Resource identification
- Interaction with resources through views
- Self contained messages
- Hypermedia as an Application State Management Engine (HATEOAS)
6. Code on demand (optional)
Now about each element in more detail.
Architecture, client - server. We separate application logic from different clients, make their code more portable, and make the server structure simpler and more scalable. Client and server development can be done completely independently.
Stateless - server. The state of the client is not stored on the server, in any form, it is the client who deals exclusively with it. This simplifies the development and maintenance of the server, making it more stable.
Cacheability A clear server query caching system should be developed, which can significantly improve performance.
Multilayer structure. The presence / absence of intermediate servers caching, load balancing, additional proxying should go completely unnoticed by customers.
Single interface.Identification of resources. Each resource has a unique
URI (Uniform Resource Identifier). For example:
/ users / ae25b8
As for ID, I advise you to look in the direction of UUID (
universally-unique identifier ), it is supported by most databases and this approach will help to ensure the cross-system uniqueness of identifiers. Example:
/ users / 550e8400-e29b-41d4-a716-446655440000.
Interaction with resources through representations. Each resource has its own unique URI (representation), and several verbs to control this representation.
Self-contained messages. Each answer must contain all the necessary information so that it can be properly processed without the help of other resources.
HATEOAS. Hypermedia As The Engine Of Application State.
Hypermedia as a mechanism for managing application states.
Words - Representational State Transfer should call in your head the appearance of a picture of a competent web application: a network of web pages (let's call them states), in which the user moves by clicking on the links (state change) to go to the next page (representing the next state of the application) .
Roy fielding
The key to understanding
HATEOAS is surprisingly simple - each response received contains a link to the following request.
Hypermedia is a content type of a resource with hypertext markup enabled. Hypertext in this context, as Fielding believes, is the simultaneous presentation of information and choice elements.
Thus, hypermedia is just an extension, which is characterized by the presence in the information content of temporary links to other content within the media stream.
Code on demand. Optional structure element. Allows you to receive the program code for its subsequent execution on the client.
Thus, if your application meets all the requirements (restrictions) described above, it can safely be called RESTful. The only exception is code on demand - this parameter is optional.
A good API is easy to understand and easy to use.
Basic REST over HTTP.
A resource is a unique object accessible at a unique URL.
Base URLs must be understood without documentation.
To begin with, it is advisable to start all the URLs of your API with a prefix, for example:
/ api /
this will help simplify API maintenance in the future. A good option may be the prefix in the domain name:
api.example.com/users/ae25b8There are 2 main types of
resource in the REST architecture: a
collection and
a collection element .
The collection is a set of independent and self-sufficient elements.
An example of a link to a collection of users:
/ api / users
An element of the user’s collection, or a specific user, in this case, can be represented as:
/ api / users / ae25b8
Nouns are good, verbs are bad.
Collection names must represent entities (plural nouns), and they must be as specific and clear as they can (self-documenting). If we are talking about dogs, then it should be dogs, not just animals.
Each resource in the RESTful API is governed by several specific minimally necessary verbs. For most cases, 4 basic verbs are enough (HTTP methods):
GET - get
POST - create
PUT - change
DELETE - delete
GET, PUT, DELETE - idempotent.
Idempotency means that no matter how many times we call such a method, the result will be the same.
Resource | POST | Get | PUT | DELETE |
---|
/ users | Create user | Show list of all users | Refresh all users list | Delete all user |
/ users / ae25b8 | Mistake | Show Vasily Pupkin | If there is, update Pupkin, if not. Error | Delete Vasily Pupkin |
Connections
If you need to show a hierarchical relationship between objects, do so.
User’s collection:
/ api / users / ae43bc / cars
Specific Machine:
/ api / users / ae43bc / cars / c7b45e
Do not write long addresses - this is bad:
/ api / users / ae43bc / cars / c7b45e / door / 346ec3bSuch addresses are not easy to read and search in the documentation, often it does not make sense at all - the identifiers are unique and “/ cars / c7b45e” is absolutely unique to “/ users / ae43bc”. This option should be reduced:
/ api / cars / c7b45e / door / 346ec3b
Errors.
It is necessary to distinguish 2 main families of status codes (HTTP Status Code):
4xx - a problem has arisen on the user's side and he can correct it himself by correctly entering the necessary information for the request.
5xx - a problem arose on the server and to solve it, the user can send a request to the support service.
Errors should be clearly described, so that not only the user knows what he needs to do, but also you are easily guided if the user sends you a request to solve the problem.
An example of a well-written error response:
HTTP Status Code: 401
{"Status": 401, "message": "Authentication Required", "code": 20003, "more_info": "http://www.example.com/docs/errors/20003"}
Remember! You write API for the same developers as you.Use the required minimum status codes in the application.
Sometimes it may be enough 3:
- 200 OK
- 400 Bad Request (invalid request)
- 500 Internal Server Error (internal server error)
If not enough, supplement as necessary:
- 201 Created (successfully created)
- 304 Not Modified (data not changed)
- 404 Not Found (not found)
- 401 Unauthorized (unauthorized)
- 403 Forbidden (access denied)
Try to evaluate the benefits of each item you add to the user. Remember that a large number, especially unnecessary elements that can confuse even experienced developers.
In some cases, it is useful to have a parameter to suppress the status of the error code, so that the client can always, if necessary, get the code 200, for example.
PUT / api / users / de840a? Supress_status_code = 200
This will add extra flexibility to your API.
Versioned.
Be sure to specify the version number, even if you do not plan to change the interface - everything can quickly change.
The version can be specified in the address bar:
/ api / v2 / users / ae43bc
or in request parameters:
/ api / users / ae43bc? v = 2
It makes no sense to make long version names, insert points in them:
v1.03Interface versions should be changed as rarely as possible, while the internal logic of the API can be changed as soon as the need arises. In reality, the current version of the API may be, for example, v2.034-beta2, but the interface version, and, accordingly, the version presented in the address will be just 2.
Paginated issue.
Any collection, however small, in your opinion, it should not be given page by page. Decide on the collection format of the collection, for example, Content-Type: application / json {"data": {}, "paging": {"limit": 50, "offset": 0, "total": 150}} always try to use the same format in all the responses of the application - make life easier for yourself and the client software developers.
It is worth choosing some default values ​​for the parameters “limit”, “offset”, and, most likely, limit the maximum value for “limit”.
Hide all complex query components behind the "?".
If you need to use different filters in your GET request, place them behind the question mark (in the URL parameters):
GET / api / users? Limit = 10 & offset = 4 & age = 30 & height = 160 & weight = 120
Give the user only what he wants.
Allow the client to receive only those fields in the request that they need:
GET / api / users / ae43bc? Fields = fitst_name, last_name, age, gender, finger_count
The format of the given data.
Do not be limited to any one format. Optional make several, for example, json and xml. This easy way can significantly simplify development for customers, and there will be no need to choose something one. The format of the returned data can be described both in the HTTP headers and in the query string:
ACCEPT: application / json
GET /api/users/ae43bc.json
And you should definitely choose some default format.
Search.
This is one of the few types of resource that is destined to remain a verb. I mean global search.
GET / api / search? Q = some + text + to + find
Again, depending on the system used by the search engine, you can apply different filters.
Some local search within the collection can also be done with simple filters:
GET / api / users? Q = some + users + to + find
Authorization
Use, if possible, the latest version of OAuth - OAuth 2.0 - this system is well known to developers, and has worked well. Why invent a bicycle?
Documentation.
This is one of the most important aspects of a good API. Anyone who has ever encountered writing client scripts will agree with me. Hours spent on good documentation, will more than pay off the long months of support service. The focus is simple - describe succinctly and clearly all the data received and transmitted, as well as the purpose of the methods. Remember! You write for programmers. It is not necessary to describe some obvious points. Give all status codes given; list all accepted parameters; describe them where necessary; give links to more detailed material; provide examples of the data obtained, if appropriate, with their description.
References
Try to give links to all related resources in the answers, if you want to comply with the HATEOAS principle, and be called RESTful. For this, the developers of client programs will love you very much - they will not have to generate these links themselves.
Now the most important thing!
Facade Pattern for API.Development of any API should begin with a detailed study of the interface. In fact, at the beginning of writing code, you should have all the URIs of your API with detailed documentation of all parameters of each method available for this URI, with all status codes and return data formats. Ideally, this interface should no longer be changed during further development. This approach greatly simplifies and speeds up work on the main API code, and allows you to simultaneously write client software at the very beginning of development.
Remember! The API interface should be as simple and clear as possible, the only way to achieve happiness and harmony.
A few words in conclusion
As a result, we and the team successfully made a social network in which we applied the REST API. The network, by the way, was on PHP, in particular Symfony2, although this approach is applicable to other technologies. I hope my first article was interesting to you. I will be glad to hear questions and opinions in the comments.
I invite to courses on web development from business school Digitov, which I lead:
I want to become Junior PHP Developer! (for beginners),
Symfony 2. Agile development (for specialists), as well as my colleagues:
Python / Django development (for beginners) and
Ruby on Rails. On rails to professional development (for beginners). Subscribe to courses now and be able to buy them at a discount.
PS To receive our new articles before others or simply not to miss new publications - subscribe to the SECL Group fan pages:
Facebook ,
VK , and
TwitterOriginal article:
http://secl.com.ua/article_rest_api_web.htmlAuthor : Sergey Kharlanchuk, Senior PHP Developer / Team Lead,
SECL GROUP / Internet Sales Technologies