Empty HTTP POST request or GET request to generate a random value through an HTTP API

23,320

Solution 1

  • Safe => whether call results in a change of state on the server.
  • Idempotent => whether multiple calls result in the same change on the server.

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.

Solution 2

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

Solution 3

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.

Solution 4

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

Share:
23,320
tugberk
Author by

tugberk

Senior Software Engineer and Tech Lead, with a growth mindset belief and 10+ years of practical software engineering experience including technical leadership and distributed systems. I have a passion to create impactful software products, and I care about usability, reliability, observability and scalability of the software systems that I work on, as much as caring about day-to-day effectiveness, productivity and happiness of the team that I work with. I occasionally speak at international conferences (tugberkugurlu.com/speaking), and write technical posts on my blog (tugberkugurlu.com). I currently work at Facebook as a Software Engineer. I used to work at Deliveroo as a Staff Software Engineer in the Consumer division, working on distributed backend systems which have high throughput, low latency and high availability needs. Before that, I used to work at Redgate as a Technical Lead for 4 years, where I led and line-managed a team of 5 Software Engineers. I was responsible for all aspects of the products delivered by the team from technical architecture to product direction. I was also a Microsoft MVP for 7 years between 2012-2019 on Microsoft development technologies.

Updated on January 30, 2020

Comments

  • tugberk
    tugberk over 4 years

    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?