REST best-practice for overlong URIs

Viewed 5303

I have REST services which should receive really long queries via GET. Say for example I want to query a service with many geographical coordinates to find out something about all this coordinates.

1) My first thought was to use long URIs and increase the max URI length of the servlet container.

It would look like this:

GET http://some.test/myresource?query={really big JSON object}

But it seems that URIs longer than 2 KB are not reliable due to old proxy servers (is that right?).

2) My workaround is to create a temporary resource via POST first and use the URI of this resource as parameter in the actual GET request. That would look like this:

POST http://some.test/temp
Request Body: {really big JSON object}

201 Created Location: http://some.test/temp/12309871

GET http://some.test/myresource?query=http://some.test/temp/12309871

3) Use body of GET request. I've read the answers to the question whether it is a good idea to use the body of a GET request for the query, and the consensus is: no. Even Roy Fielding says that this is a bad idea.

4) Another approach could be to interpret POST as "create query result resource" and delete this resource after the request. But I consider that to be not RESTful and to be a bad idea.

Is there a better way to handle big queries with GET requests?

6 Answers

I thought that the whole point in REST was to work on "documents" (or something alike). The URI part of a request is there to identify uniquely the resource to work on. The body part in contrast is there for the "contents" part of the document.

Hence, use the "body" part of the request.

Also note that the semantics of a "GET" request isn't supposed to be used for "PUTTING" or "POSTING" documents (comment in relation to your "query" example above which seems to "create" an object).

In any case, as you have pointed out, the URI part is limited (for good reason I am sure).


If you are concerned with caching, then the use of ETag/Last-Modified fields (in conjunction with "conditional GET" helps for this purpose.

Here is a slight variation on your second option. Create yourself a processor resource called QueryMaker. POST your parameters to it and let it redirect you to a temporary query resource that will return your results.

POST /QueryMaker
Body: Big Json representation of parameters

303: See Other
Location: http://example.org/TemporaryQueries/123213

If you are using a GET request to send large objects, you are not using REST correctly.

  • GET should be used for retrieving resources (via some sort of unique identifier)
  • POST should be used for creating resources (with the contents in the body)
  • PUT should be used for updating a resource (with the contents in the body)
  • DELETE should be used for deleting a resource

If you follow these guidelines you will never have to have overly long URIs.

Some best practice REST guidelines are here: http://www.xml.com/pub/a/2004/08/11/rest.html

Can't you just send the big JSON data with the GET request body, instead of creating the temp resource?

Although it's not 100% kosher, i've found it works nicely with firefox and IE and IMO, the querystring is inelegant and usually exposes implementation details that don't belong in the URI. Just make sure to add a cache buster querystring parameter if you need up-to-date data because the server will ignore the data when determining whether it can return a cached response.

See here for a discussion of pros and cons of stuffing data in the GET request body.

Related