HTTP Get一定是冪等的嗎?
今天分析抓包的時候, 主要研究POST請求, 然后想到, 有沒可能程序員為了隱藏接口, 把修改操作放在了響應GET請求的時候。后來想了想, GET應該是冪等的,沒人會這么做的。
然而突發奇想想到了一個問題, 各大網站的訪問量的統計不就正是發送了GET請求后, 后端將訪問量+1嗎,這不是破壞了冪等性嗎?
於是開始百度,基本無果,搜的到的內容太少了,google后在stackoverflow找到了如下這個問題,和我的疑惑一樣,來看一下吧
Problem description
I'm trying to understand REST. Under REST a GET must not trigger something transactional on the server (this is a definition everybody agrees upon, it is fundamental to REST).
So imagine you've got a website like stackoverflow.com (I say like so if I got the underlying details of SO wrong it doesn't change anything to my question), where everytime someone reads a question, using a GET, there's also some display showing "This question has been read 256 times".
Now someone else reads that question. The counter now is at 257. The GET is transactional because the number of views got incremented and is now incremented again. The "number of views" is incremented in the DB, there's no arguing about that (for example on SO the number of time any question has been viewed is always displayed).
So, is a REST GET fundamentally incompatible with any kind of "number of views" like functionality in a website?
So should it want to be "RESTFUL", should the SO main page either stop display plain HTML links that are accessed using GETs or stop displaying the "this question has been viewed x times"?
Because incrementing a counter in a DB is transactional and hence "unrestful"?
EDIT just so that people Googling this can get some pointers:
From http://www.xfront.com/REST-Web-Services.html :
- All resources accessible via HTTP GET should be side-effect free. That is, the request should just return a representation of the resource. Invoking the resource should not result in modifying the resource.
Now to me if the representation contains the "number of views", it is part of the resource [and in SO the "number of views" a question has is a very important information] and accessing it definitely modifies the resource.
This is in sharp contrast with, say, a true RESTFUL HTTP GET like the one you can make on an Amazon S3 resource, where your GET is guaranteed not to modify the resource you get back.
But then I'm still very confused.
Answer
What matters is that from a client point of view GET is safe (has no side effects) by definition and that a client therefore can safely call GET any number of times without considering any side effect that might have.
What a server does is the server's responsibility. In the case of the view counter the server has to make the decision if it considers the update of the counter a side effect. Usually it won't because the counter is part of the semantic of the resource in the first place.
However, the server might decide NOT to increment the counter for certain requests, such as a GET by a crawler.
---Jan, From StackOverflow
仔細品下面這段話
Idempotency is important in building a fault-tolerant API. Suppose a client wants to update a resource through POST. Since POST is not a idempotent method, calling it multiple times can result in wrong updates. What would happen if you sent out the POST request to the server, but you get a timeout. Is the resource actually updated? Does the timeout happened during sending the request to the server, or the response to the client? Can we safely retry again, or do we need to figure out first what has happened with the resource? By using idempotent methods, we do not have to answer this question, but we can safely resend the request until we actually get a response back from the server.
Be careful when dealing with safe methods as well: if a seemingly safe method like GET will change a resource, it might be possible that any middleware client proxy systems between you and the server, will cache this response. Another client who wants to change this resource through the same URL (like: http://example.org/api/article/1234/delete), will not call the server, but return the information directly from the cache. Non-safe (and non-idempotent) methods will never be cached by any middleware proxies