Forums Register Login

RESTful APIs: GETs with bodies?

+Pie Number of slices to send: Send
OK, I've done some poking around, and it seems that the HTTP Specification doesn't specifically prohibit GET request with bodies, but it's just something doesn't get done very often. In fact, libraries like HttpClient don't even allow it (hence my question here).

As we know, GETs should be used when a resource is being queried with no effects on the server state.

What I'm thinking of is a GET that obtains a list of resources based upon search criteria that is on the complicated side -- too lengthy and too complicated to flatten into a simple name/value query string. An XML representation is perfect, but because of the no-body nature of the traditional GET, there's really no way to send such information along.

What say you RESTers? How would you handle this?

Simply defining it as a POST (or worse, a PUT) simply so that the search criteria can be carried in the request body seems to violate the precepts of REST and feels just plain dirty.
+Pie Number of slices to send: Send
P.S. I found this while poking around.
+Pie Number of slices to send: Send
 

Originally posted by Bear Bibeault:
What I'm thinking of is a GET that obtains a list of resources based upon search criteria that is on the complicated side -- too lengthy and too complicated to flatten into a simple name/value query string. An XML representation is perfect, but because of the no-body nature of the traditional GET, there's really no way to send such information along.



The RESTian way to deal with this is to create a query result resource.
  • POST the query representation to the parent search resource. A successful search will return the result resource URI.
  • GET the result resource representation.


  • How long you intend to keep your result resource around is up to you. If the searched space is fairly static you can reuse the result for duplicate queries for a limited amount of time. You could even allow the creator to DELETE the result (though a timeout would still be necessary).

    A GET with a body wouldn't be considered RESTful - in my opinion - because the search result wouldn't have a unique URI as it is the case with query parameters in the URI. A GET with a body is RPC all over again ...
    [ November 20, 2008: Message edited by: Peer Reynders ]
    +Pie Number of slices to send: Send
     

    Originally posted by Peer Reynders:
    The RESTian way to deal with this is to create a query result resource.

    Ah. I hadn't considered a 2-phase, dynamic resource approach.

    Can you tell I'm new to this REST stuff?

    A GET with a body wouldn't be considered RESTful - in my opinion - because the search result wouldn't have a unique URI as it is the case with query parameters in the URI.

    Got it!

    Thanks.
    +Pie Number of slices to send: Send
     

    Originally posted by Peer Reynders:
    If the searched space is fairly static you can reuse the result for duplicate queries for a limited amount of time.



    Another scenario for a dynamic search space would be that the result resource implementation actually stores the query - so it processes the query every time a GET is performed on it, returning an updated result representation. The resource's lease on life could be extended every time it experiences a GET. Furthermore the client could submit a desired life span for the result resource in the query representation - in case an (automated) client wants to periodically repeat the query.

    The only problem with this implementation is that the resource's representation wouldn't be cache-able any longer, as it could change at any point of time. You could still save sending identical representations over the wire by supporting conditional-GET (with the If-None-Match HTTP Header); that would require that you send back an ETag HTTP Header that contains the hash sum for the result representation for every normal GET. Once you have that in place you have the motivation to place implementation optimizations for detecting whether a new result set will differ from an earlier one.

    As you can see the RESTful approach tends to create more opportunities for achieving scalability compared to an RPC-oriented approach (that doesn't mean that it comes for free).

    I also didn't explicitly mention that the result resource would be a sub-resource to the parent search resource ("parent" was meant to imply that).
    [ November 20, 2008: Message edited by: Peer Reynders ]
    +Pie Number of slices to send: Send
     

    Originally posted by Peer Reynders:
    I also didn't explicitly mention that the result resource would be a sub-resource to the parent search resource ("parent" was meant to imply that).


    Could you expand that into a larger paragraph?
    +Pie Number of slices to send: Send
    A crude example:



    So by URI design /query/results/A34FA0095 is a sub-resource to /query/results - /query/results is the "parent" of /query/results/A34FA0095. I call this crude because best practices dictate that you should use "meaningful" URIs. The context decides what is meaningful. A contrived example would be /query/results/USA/Houston/A34FA0095 - it could mean that the query's "most significant" query parameter values are "USA" and "Houston" while the hash value for the complete set of query parameter names and values is "A34FA0095".
    [ November 20, 2008: Message edited by: Peer Reynders ]
    +Pie Number of slices to send: Send
    Excellent. That gives me enough of a framework to move on this. Thanks muchly!
    Farmers know to never drive a tractor near a honey locust tree. But a tiny ad is okay:
    a bit of art, as a gift, the permaculture playing cards
    https://gardener-gift.com


    reply
    reply
    This thread has been viewed 14889 times.
    Similar Threads
    Java sound: how to play a file?
    Astral Projection
    How to get response code and message when using jersey client
    RESTful query query #2: Executing a stored query
    Difference between GET and POST
    More...

    All times above are in ranch (not your local) time.
    The current ranch time is
    Apr 16, 2024 09:45:40.