Reputation: 58484
In my HTTP API, one of the endpoints should return an randomly generated value and that value will be associated with the authenticated caller of the endpoint. Currently, I have the following structure:
GET http://example.com/random-ticket HTTP/1.1
Authorization: Basic base64-encoded-basic-auth-value
Accept: application/json
Host: example.com
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: application/json; charset=utf-8
Date: Thu, 03 Oct 2013 07:25:56 GMT
Content-Length: 59
{"user-ticket":"Pfa42634e-1a2e-4a7d-84b9-2d5c46a8dd81"}
A GET request is issued to retrieve the random value. However, HTTP GET calls should be idempotent and my above implementation is not obeying that rule. On the other hand, I'm not sure if it's OK to issue HTTP POST requests with an empty message body.
What is the right way of performing this type of operations by the HTTP book?
Upvotes: 16
Views: 28032
Reputation: 16524
You should be using POST
in this case because, by desgin, GET
calls can be cached. Regarding empty post body, there is no issue. A similar scenarios is also discussed at: POST with empty body, in which one post mentions:
a POST with no content-length and no body is equivalent to a POST with Content-Length: 0 and nothing following, as could perfectly happen when you upload an empty file for instance. The resource is determined by the URL and the server has to know how to handle the body, including if it's empty. I don't see the issue here in fact :-/
Willy
Upvotes: 1
Reputation: 8445
There is no problem having a random generator with a GET as there is no server state that is being stored. In the same way you could have a calculator that accepts params and adds them when a GET is called. The question about cachable is an interesting one, though doesn't really apply to a random generator as the resource by nature is not cached. That still doesn't change the fact that it can be designed in a safe/idempotent fashion.
As to POST without a body, or even using params in a query string, that is fine. The key thing about POST is that it 'may' result in a change to the server. It's not guaranteed either that it will, but you can't assume it won't as with a GET. Whether or not there is any content being set, doesn't change the fact that there can be a change. For example imagine a fictitious resource "\counter\increment". Each time you POST to it it will cause \counter to increment. I haven't sent any payload, but I am causing a change in server state thus it should be POST or PUT.
Upvotes: 5
Reputation: 81680
So the question is not the data that is returned. Rather it is the server state: so if you are storing this value on the server this results in a change in the state, then it is not fit for GET. Otherwise if it is the data that is returned, it is fine. Call to http://stackoverflow.com returns different data if called 10 minutes apart.
Let's look at another example, a Clock service which returns the current time. Everytime you make the call, you get a different value but the call itself does not result in a change in the state on the server since the clock state is maintained separately. So using GET here is a good choice.
Upvotes: 18
Reputation: 27187
There is absolutely nothing in the HTTP prohibiting the use of POST with an empty body.
Moreover, message carries a representation, which is body + headers. In your case body is 0 length, which is fine, and the headers which identify the user.
See discussion here - http://lists.w3.org/Archives/Public/ietf-http-wg/2010JulSep/0273.html
Upvotes: 12