Safe methods and idempotency of http

Recently I was researching http, and I saw the security method and idempotency of http, but I didn’t quite understand it, especially the “post method is non-idempotent”. I checked the information and found the following two valuable articles. come over!
Understand HTTP idempotency
from: http://www.cnblogs.com/weidagang2046/archive/2011/06/04/2063696.html

Web API based on HTTP protocol is the most popular way to provide distributed services nowadays. Whether in large-scale Internet applications or enterprise-level architectures, we have seen more and more SOA or RESTful Web APIs. Why are Web APIs so popular? I think a lot of it is due to the simple and efficient HTTP protocol. The HTTP protocol is a distributed resource-oriented network application layer protocol. It is very simple whether the server provides Web services or the client consumes Web services. Coupled with the development of browsers, Javascript, AJAX, JSON, HTML5 and other technologies and tools, the design of Internet application architecture shows the transition from traditional server-side dynamic web pages such as PHP, JSP, ASP.NET to Web API + RIA (Rich Internet application) transition trend. Web API focuses on providing business services, RIA focuses on user interface and interaction design, and the division of labor between the two fields has become clearer since then. In this trend, Web API design will become a required course for server-side programmers. However, just as simple Java language does not mean high-quality Java programs, simple HTTP protocol does not mean high-quality Web API. In order to design a high-quality Web API, it is also necessary to have a deep understanding of the characteristics of distributed systems and the HTTP protocol.

The definition of idempotency

This article is about to discuss an important property of the HTTP protocol: idempotence (Idempotence). The definition of idempotency in the HTTP/1.1 specification is:

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.


By definition, the idempotency of HTTP methods means that a single request to a resource should have the same side effects as multiple requests. Idempotency belongs to the semantic category, just as the compiler can only help to check for syntax errors, the HTTP specification has no way to define it through syntax means such as message format, which may be one of the reasons why it is not given much attention. But in fact, idempotency is a very important concept in distributed system design, and the distributed nature of HTTP also determines its important position in HTTP.

Distributed transactions vs idempotent design

Why do you need idempotency? Let's start with an example. Suppose there is a remote API for withdrawing money from an account (it may or may not be HTTP), we temporarily record it as a function-like method:

bool withdraw(account_id, amount)

The semantics of withdraw are The amount of money is deducted from the account corresponding to account_id; if the deduction is successful, it returns true, and the account balance decreases by the amount; if the deduction fails, it returns false, and the account balance remains unchanged. It is worth noting that we cannot easily assume the reliability of a distributed environment compared to a local environment. A typical situation is that the withdraw request has been correctly processed by the server, but the result returned by the server is lost due to network and other reasons, so that the client cannot know the processing result. If it is on a web page, some inappropriate design may make the user think that the last operation failed, and then refresh the page, which causes withdraw to be called twice and the account to be debited one more time. As shown in Figure 1: The first solution to this problem in

Figure 1

is to use distributed transactions, and ensure the transactional nature of the withdraw function by introducing middleware that supports distributed transactions. The advantage of distributed transactions is that it is very simple for the caller, and the complexity is handed over to the middleware to manage. The disadvantage is that on the one hand, the architecture is too heavy, and it is easy to be tied to specific middleware, which is not conducive to the integration of heterogeneous systems; on the other hand, although distributed transactions can ensure the ACID nature of transactions, they cannot provide performance and availability. guarantee.

Another more lightweight solution is an idempotent design. We can make withdraw idempotent through some tricks, such as:

int create_ticket()
bool idempotent_withdraw(ticket_id, account_id, amount)


The semantics of create_ticket is to obtain a unique processing number ticket_id generated by the server, which will be used to identify subsequent operations. The difference between idempotent_withdraw and withdraw is that a ticket_id is associated. The operation represented by a ticket_id will only be processed once at most, and each call will return the processing result of the first call. In this way, idempotent_withdraw is idempotent, and the client can safely call it multiple times.

In the idempotent-based solution, a complete withdrawal process is decomposed into two steps: 1. Call create_ticket() to obtain ticket_id; 2. Call idempotent_withdraw(ticket_id, account_id, amount). Although create_ticket is not idempotent, under this design, its impact on the system state can be ignored, plus idempotent_withdraw is idempotent, so any step fails or times out due to network and other reasons, the client can retry until Get results. As shown in Figure 2:


Figure 2

Compared with distributed transactions, the advantages of idempotent design lie in its lightweight, easy adaptation to heterogeneous environments, as well as performance and availability. In some applications with high performance requirements, idempotent design is often the only choice.

Idempotency of HTTP

The HTTP protocol itself is a resource-oriented application layer protocol, but there are actually two different ways to use the HTTP protocol: one is RESTful, which treats HTTP as an application layer protocol and more faithfully abides by the HTTP protocol The other is SOA, which does not completely regard HTTP as an application layer protocol, but regards HTTP protocol as a transport layer protocol, and then establishes its own application layer protocol on top of HTTP. The HTTP idempotency discussed in this article is mainly for the RESTful style, but as we saw in the previous section, idempotency does not belong to a specific protocol, it is a feature of distributed systems; therefore, whether it is SOA Either RESTful Web API design should consider idempotency. The following will introduce the semantics and idempotency of the four main methods of HTTP GET, DELETE, PUT, and POST.

The HTTP GET method is used to obtain resources and should not have side effects, so it is idempotent. For example: GET http://www.bank.com/account/123456, will not change the state of the resource, no matter if it is called once or N times, there is no side effect. Note that the emphasis here is that once and N times have the same side effects, not that the result of each GET is the same. The HTTP request GET http://www.news.com/latest-news may get different results each time, but it does not produce any side effects, so it is idempotent.

The HTTP DELETE method is used to delete resources and has side effects, but it should satisfy idempotency. For example: DELETE http://www.forum.com/article/4231, calling once and N times has the same side effect on the system, that is, deleting the post with id 4231; therefore, the caller can call or refresh multiple times page without worrying about causing errors.

The more confusing ones are HTTP POST and PUT. The difference between POST and PUT is easily mistaken as "POST means creating resources, PUT means updating resources"; in fact, both can be used to create resources, and the more essential difference is in idempotency. POST and PUT are defined in the HTTP specification as follows:

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line ...... If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header.

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.


The URI corresponding to POST is not the created resource itself, but the recipient of the resource. For example: The semantics of POST http://www.forum.com/articles is to create a post under http://www.forum.com/articles, and the HTTP response should include the creation status of the post and the URI of the post. Two identical POST requests will create two resources on the server side with different URIs; therefore, the POST method is not idempotent. The URI corresponding to PUT is the resource itself to be created or updated. For example: the semantics of PUT http://www.forum/articles/4231 is to create or update the post with ID 4231. The side effects of doing multiple PUTs to the same URI are the same as doing a single PUT; therefore, the PUT method is idempotent.

After introducing the semantics and idempotency of several operations, let's take a look at how to implement the aforementioned withdrawal function in the form of Web API. Very simple, use POST /tickets to implement create_ticket; use PUT /accounts/account_id/ticket_id&amount=xxx to implement idempotent_withdraw. It is worth noting that strictly speaking the amount parameter should not be part of the URI, the real URI should be /accounts/account_id/ticket_id, and the amount should be placed in the request body. This mode can be used in many situations, such as: preventing accidental duplicate posts in forum sites.

Summary The
above briefly introduced the concept of idempotency, the method of replacing distributed transactions with idempotent designs, and the semantics and idempotency characteristics of HTTP's main methods. In fact, if you want to go back to the source, idempotency is a concept in mathematics, which expresses that the result of N transformation is the same as that of 1 transformation. Interested readers can learn more about it from Wikipedia

Reference : http://blog.csdn .net/xyls12345/article/details/23951469

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327058896&siteId=291194637