11

Earlier this week, I had to do something which feels like a semantics violation. Let me explain.

I was making a simple AJAX client application, which was to make a request to a service with a given number of parameters. Since the whole app is basically read-only, I thought that using HTTP GET was the way to go. Some of the parameters that I had to pass were simple (such as the sort order, or page number).

However, one of the required parameters could be of variable length, and this made me worry. Since I was encoding all of the parameters in the querystring of the GET request, it seemed to me that this placed an unnecessary upper limit of (roughly) 2000 characters for the request URL. And regardless, I didn't like seeing 500-character-long request URLs.

So, since a POST request doesn't have a limitation like that, I decided to switch. But this doesn't feel right. I am under the impression that a POST denotes modification of data - but I'm using it for a simple read-only request.

Is there a better way to do this? To perform a GET, with many parameters? I've heard of one method - where you perform a preliminary POST of the parameters themselves, and then perform a GET. But, this technique leaves much to be desired.

But looking past this specific case, what are the real semantics and limitations of HTTP request methods? And why does GET not support any kind of parameter payload? Using the querystring in the URL almost feels like a hack to me.

Community
  • 1
  • 1
voithos
  • 68,482
  • 12
  • 101
  • 116
  • Why do you feel that post denotes data modification? – Conrad Frix Jun 10 '12 at 05:23
  • 2
    @ConradFrix: Because of it's use in submitting forms, in uploading files, and [general non-idempotent actions.](http://en.wikipedia.org/wiki/POST_(HTTP)#Affecting_server_state) – voithos Jun 10 '12 at 05:26
  • If you're writing an Ajax application, why do you care what the URL length? Also note that the 2000 character limit applies to browser URLs only, not Ajax requests (as noted in the comments to the link you presented). – Jonathan W Jun 10 '12 at 05:43
  • @JonathanW: I just tried some test AJAX requests, and that doesn't seem to be the case. With 1000 characters, I get a 404 Not Found (because I'm using a bogus URL). With 2000 characters, I get a 400 Bad Request, so it fails. With 100000 characters, I don't get a response at all. – voithos Jun 10 '12 at 05:53

1 Answers1

16

A few points on this issue:

  • The HTTP spec (RFC 2616) doesn't forbit GET requests to have parameters, so it's not a matter of the semantics of HTTP GET itself. However, many HTTP stacks (for clients, services, or proxies) forbid bodies in HTTP requests, the fact that you can't use them is mostly an implementation detail (quite prevalent) than a semantic issue with the HTTP GET requests
  • Similarly, the limitation of the URI (or query string) length isn't specified on the RFC either. It's mostly a security mitigation implemented by several HTTP server stacks to prevent a bad client from consuming server resources (for example, in IIS/ASP.NET the default limit is 2k but you can increase it via some elements in web.config). Again, it's not a semantic but a practical issue.
  • POST requests do indicate data modification if you're following the REST philosophy, but there are many examples of HTTP POST requests used for read-only operations. SOAP uses POST in all of its requests, regardless of whether the operation it is calling is a "safe" or a "modifying" one. So you can use POST for those operations as well. However, by deviating from the REST (and the "canonical" HTTP) usage, you'll lose some of the features of the protocol, such as caching which can be applied for GET requests, but not for POST.
  • Your example of using two requests (POST with parameters + GET to "get" the results) seems overkill. As I mentioned, POST requests don't necessarily mean modifying resources, so you don't have to create a new "protocol" (POST+GET) to access your operation when one request is enough.
carlosfigueira
  • 85,035
  • 14
  • 131
  • 171
  • 3
    +1 nice answer, another important point: GET is supposed to be idempotent, so it can (and is) automatically retried by the client, POST is never retried. – Francis Upton IV Jun 10 '12 at 14:53