Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST best-practice for overlong URIs

Tags:

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?

like image 601
deamon Avatar asked Jan 15 '10 10:01

deamon


People also ask

Should HTTP verbs be used in URIs?

HTTP verbs are preferred if possible, as they are part of the HTTP protocol and as such a standard. It also allows you to use existing security and caching layers on a standard web server, without having to write any bespoke middleware.

What is format of a URI in REST architecture?

URIs are identifiers of resources that work across the Web. A URI consists of a scheme (such as http and https ), a host (such as www.example.org ), a port number followed by a path with one or more segments (such as /users/1234 ), and a query string.

What is a URI rest?

URI. REST APIs use Uniform Resource Identifiers (URIs) to address resources. REST API designers should create URIs that convey a REST API's resource model to the potential clients of the API. When resources are named well, an API is intuitive and easy to use.


2 Answers

Use PUT.

Why? For the following reasons:

  • Just because the verb PUT 'may update' the resource, doesn't mean it will or must alter underlying state of the resource.
  • No new resource identifier (url) should be created by the API side of a PUT. Yes, technically a PUT with a client specified identifier is possible, but in this case you're hitting an existing resource.
  • PUT is like GET in the fact that it should be idempotent, meaning the results of the request will always be the same regardless of how often you call it and it has no side effects.

PUT means you're putting resource data to an existing resource. In terms of a article or post in the document / blog post worlds, it would be like uploading a new revision of some document to an existing resource URL. If you upload the same revision to the same URL, nothing should change in the resource you get back.

In your case, the geo data is some new resource data you're uploading and the result you get back should be the same every time you make the same request.

A more purist method to use the GET verb for the request might be:

  • Create an endpoint for a query resource type
  • POST the JSON set of query details to a query resource endpoint and get an identifier for the query resource (say it returns a query id of 123)
  • Submit to the get request a query identifier http://some.test/myresource?query_id=123
  • Delete the query resource 123

I see the pure method much more overhead than using PUT with query resource data in the body.

like image 71
Ray Avatar answered Dec 20 '22 01:12

Ray


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.

like image 27
jldupont Avatar answered Dec 20 '22 00:12

jldupont