"A Shuttle: All REST APIs use POST" restful api post, get, put, delete selection

The reason for this article is mainly because of this post on V2EX, which said——

"The interface to connect with colleagues, all the interfaces he defined are post requests. The reason is that https is more secure to use post. I used to use restful api before. If only post requests are safe for https? Then why do we need get, put, and delete? ? How should I refute him."

Then there are a lot of arguments in this post, 1) POST is very good, so it should be done like this, with little communication, 2) Just a shuttle, finish work early and go home early, 3) So what if you win the fight ? It's just work, elegance can't be eaten as a meal. Although the comments are not overwhelming, there are also a large number of people who support it. Then, I mocked it on Twitter, using POST to do everything is like seeing a decoration worker coming to your house and saying, "I work by nailing everything, such as screws, bolts, snaps, latches... all are useless, nails One shot, convenient, fast, safe, and go home early after work... However, there are still some netizens who think that using POST is good, and it can save time. So, just right, I am in the "Principles of My System Architecture" In the "Principle 5" in the objection API return code is 200, whether it is right or wrong, I wrote this article specifically to set the record straight.
This article is mainly divided into the following parts:

  • Why different HTTP verbs?
  • Restful for complex queries
  • Responses to several main questions
  • Is POST more secure?
  • Can using all POST save time and communicate less?
  • The correct posture to go home early
  • It's just work, elegance can't be eaten

Why use different HTTP verbs

Generally speaking, there are two kinds of logic in the programming world: " business logic " and " control logic ".

  • business logic . It is the code that you implement the function of business requirements, and it is the code that is strongly related to user needs. For example, save the data submitted by the user, query the user's data, complete an order transaction, refund the user... etc., these are business logic
  • control logic . It is the non-functional code that we use to control the operation of the program. For example, the variables and conditions used to control the program loop, the use of multi-threaded or distributed technology, the use of HTTP/TCP protocol, what kind of database to use, what kind of middleware... etc., these things have nothing to do with user needs .

The same is true for network protocols. Generally speaking, almost all mainstream network protocols have two parts, one is the protocol header and the other is the protocol body. The protocol header is the data to be used by the protocol itself, and the protocol body is the user's data. Therefore, the protocol header is mainly used for the control logic of the protocol, while the protocol body is the business logic.

The verb (or Method) of HTTP is in the protocol header, so it is mainly used for control logic.

The following is the verb specification of HTTP. Generally speaking, REST API requires developers to strictly follow the following standard specifications (see RFC7231 section 4.2.2 – Idempotent Methods)

insert image description here
Among them, PUT and PACTH both update the business resource information. If the resource object does not exist, you can create a new one, but the difference between them is that PUT is used to update all the complete information of a business object, just like we submit all the resources through the form. data, while PACTH operates on more API-oriented data update operations, and only needs more fields that need to be updated (see RFC 5789).

Of course, in the real world, the API may not be understood strictly in accordance with the CRUD of database operations. For example, you have a login API /login. Do you think this API should be GET, POST, PUT or PATCH? When logging in, users need Enter the user name and password, and then compare it with the one in the database (select operation), and return a login session token, and then this token is used as the status token for user login. According to the above table, it should be a select operation to perform GET, but semantically speaking, login is not a query information, it should be an update of the user status or a new operation (new session), so POST should still be used, and /logout You can use DELETE. Let me explain here, don't use the CRUD of the database to correspond to these verbs mechanically. In many cases, you still need to analyze the business semantics.

In addition, we noticed that "idempotence" is added to the last column of this table. The idempotence of API is a very important thing for control logic . The so-called idempotence means that the result of executing the API multiple times and executing it once is exactly the same, without side effects.

  • POST is used to add new data, for example, to add a new transaction order, which must not be idempotent

  • DELETE is used to delete data. The result of deleting a data multiple times is the same as deleting it once, so it is idempotent

  • PUT is used for all data updates, so it is idempotent.

  • PATCH is used for local updates. For example, updating a field cnt = cnt+1 is obviously not an idempotent operation.

    The feature of idempotence is a very important thing for remote calls. That is to say, remote calls often cause timeout calls due to network reasons. For timeout requests, we cannot know whether the server has received the request and executed it. Now, at this point, we can't retry the request rashly, it will be disastrous for calls that are not idempotent. For example, for business logic such as transfer, the result of one transfer is different from that of multiple transfers. If it is repeated, it may be transferred one more time. So, at this time, if your API complies with the specification of HTTP verbs, then you can understand under which verbs you can retry and under which verbs you cannot retry when you write the program. If you use POST to express all APIs, it will be completely out of control.

In addition to control logic such as idempotence, you may also have the following control logic requirements:

  • cache . The API is cached through a CDN or a gateway. Obviously, we need to suggest caching on the query GET operation.
  • flow control . You can perform more granular flow control through HTTP verbs, for example: limit the frequency of API requests, and the read operation should be different from the write operation.
  • routing . For example: write requests are routed to the write service, and read requests are routed to the read service.
  • authority . More fine-grained permission control and auditing can be obtained.
  • monitor . Because the API performance of different methods is different, performance analysis can be done separately.
  • pressure test . When you need to stress test the API, if there is no distinction between verbs, I believe your stress test will be difficult to do.
  • ... Wait
    , maybe, you will say, my business is too simple, there is no need to make it so complicated. OK, there is no problem, but I think that in the worst case, you need to achieve "separation of reading and writing", that is to say, there must be at least two verbs, GET means a read operation, and POST means a write operation.

Restful complex query

Generally speaking, for query APIs, there are mainly four operations to be completed: sorting, filtering, searching, and paging. Below are some relevant specifications. Refer to the two best Restful API specification documents I think are written, Microsoft REST API Guidelines, Paypal API Design Guidelines.

  • Sort. For sorting the result set, use the sort keyword, and the related syntax {field_name}|{asc|desc},{field_name}|{asc|desc}. For example, an API needs to return a list of companies, sorted by certain fields, such as: GET /admin/companies?sort=rank|asc or GET /admin/companies?sort=rank|asc,zip_code|desc

  • filter . For filtering of result sets, use the filter keyword, and the syntax of {field_name} op{value}. For example: GET /companies?category=banking&location=china . However, sometimes, we need a more flexible expression, we need to construct our expression on the URL. Here you need to define six comparison operations: =, <, >, <=, >=, and three logical operations: and, or, not. (Some special characters in the expression need to be escaped, for example: >= into ge) So, we will have the following query expression: GET /products?$filter=name eq 'Milk' and price lt 2.55 Find all milk whose price is less than 2.55.

  • search . For related searches, use the search keyword, as well as the keyword. Such as: GET /books/search?description=algorithm or direct full-text search GET /books/search?key=algorithm.

  • paging . For paging processing of result sets, paging must be a default behavior, so that a large amount of returned data will not be generated.

    • Use page and per_page to represent the page number and the amount of data per page, for example: GET /books?page=3&per_page=20.
    • optional . The page method mentioned above is to use relative positions to obtain data. There may be two problems: performance (large data volume) and data deviation (high frequency update). At this time, the absolute position can be used to obtain data: record in advance the ID, time and other information of the last data in the currently obtained data, so as to obtain "data before this ID" or "data before this moment". Example: GET /news?max_id=23454345&per_page=20 or GET /news?published_before=2011-01-01T00:00:00Z&per_page=20.

In addition, for some more complex operations, it is recommended to call multiple APIs separately. Although this will increase the number of network requests, this can make the back-end program and data less coupled, and it is easier to become a micro The architecture of the service.

Finally, if you want to use a query language like GraphQL in Rest, you can consider a solution like OData. OData is an acronym for Open Data Protocol, originally developed by Microsoft in 2007. It is an open protocol that enables you to create and consume queryable and interoperable RESTful APIs in a simple and standard way.

Responses to several main questions

1) Why should the API be Restful and conform to the specification?
Restful API can be regarded as an HTTP specification and standard. You can say it is a best practice. In short, it is a consensus on HTTP API in the world. Based on this consensus, you can enjoy many technical dividends at no cost, such as: CDN, API gateway, service governance, monitoring...etc. These are the reasons that allow you to greatly reduce R&D costs and avoid pitfalls.

2) Why doesn't "premature optimization" apply to API design?
Because the API is a contract, once it is used, it is difficult to change it. Even if you release a new version of the API, you have to drive various callers to upgrade their calling methods. Therefore, interface design is like database schema design. Once the design is completed, it will be more difficult to change it in the future. Therefore, it is still necessary to design well. Just like the few documents I gave earlier - Microsoft REST API Guidelines, Paypal API Design Guidelines or Google API Design Guide are all good Guidelines for you to design APIs.

3) Is POST more secure?
Won't.

Many students think that the request data of GET is in the URL, but that of POST is not, so they think that POST is more secure. This is not the case, the HTTP URL PATH of the entire request will be encapsulated in the HTTP protocol header. As long as it is HTTPS, it is safe. Of course, some gateways such as nginx will log the URL, or put it in the history of the browser, so some people will say that GET requests are not safe, but POST is not much better, the most common in CSRF In terms of security issues, it is completely for POST. Safety is a complicated thing, and no matter which method or verb you use, it will not mean that you will be safer.

In addition,
4) Can all use of POST save time and reduce communication?
Not only will it not, but it will be worse.

People who say this kind of thing, I don't think they can think about the problem.

First, assign different verbs to the API, which takes almost no time. It is also a good programming style to write CRUD under different functions. In addition, almost all development frameworks now support very fast CRUD development, such as Spring Boot, which basically does not need to write SQL language-related query codes for writing database CRUD, which is very convenient.
Second, using a standardized method can save the learning cost of new team members, and can greatly reduce the cost of cross-team communication. Norms and standards are actually saving team time and improving overall efficiency, which is the basis for our entire human beings to collaborate. Therefore, there are many standards in this world. As long as you follow this standard, your parts can be adapted to other manufacturers' products. without communicating with each other.
Third, all use the POST interface, which is not standardized or standard. People who use your copycat API will have to keep asking you, which increases communication. In addition, maybe you develop business functions very quickly, but when you are doing control logic, you have to rework. In the long run, you owe technical debt, which leads to greater costs.

5) The correct posture to go home early
Don’t think that you will be fine when you go home. If your code has such and other problems, others can understand it, or if your code is misused and there is a problem, then you should return early What is the meaning of home? You will also be interrupted, and even called to the company to deal with the problem. Therefore, what you should do is to "go home early" in the long term, not "go home early in the short term". It should be like going home early in the long term, usually like this:

Organize and design the code well for better scalability. In this way, when facing new requirements, you can change the code less or even not. That way you can go home early. Otherwise, every time a demand comes, you have to rewrite it. How can you go home early?
Your code quality is good, with good documentation and comments. Therefore, others will not always come to you with problems, or ask you to deal with problems after you get off work. Anyone can even easily take over your code, so that you may really not be bothered

6) It’s just work, elegance can’t be eaten as a meal.
Respond to two points:

First, it’s just following a standard. Calling “normal” “elegant” shows how low the standard is. Such a low standard can only "survive for food".

Second, as a "professional programmer", you must learn to love and respect your profession. The most important thing to love your profession is not to let laymen look down on this profession. If you don't respect this profession yourself, how can you let others respect it? Respecting one's profession is not only about getting enviable remuneration, but also making one's profession more valuable.

I hope everyone can respect their profession and become a real professional programmer, not a code farmer!
insert image description here

ps Reprinted from: Left Ear Mouse Teacher Cool Shell – CoolShell https://coolshell.cn/articles/22173.html

Guess you like

Origin blog.csdn.net/qq_31686241/article/details/126801178