2

I think the standard approach to RESTful searching is this:

GET /users?parameter1=value1&parameter2=value2&parameter3=value3&parameter4=value4

But I want to do something like this:

GET /users
# Request body:
{
    "parameter1": "value1",
    "parameter2": "value2",
    "parameter3": "value3",
    "parameter4": "value4"
}

Update: I can't use GET in the above manner because some devices to not respect body content of GET requests. So I would have to use POST instead.

Is RESTful religiosity the only reason that I shouldn't use POST to send JSON data to an /api/search endpoint, as opposed to using the URI?

Are there any technical and demonstrable dangers in using POST in this manner?

I'm aware that this is similar to the following:

How to design RESTful search/filtering?

But I'm asking something more specific: namely, what are some reasons that this would be a bad approach, other than "it doesn't fit convention".

Community
  • 1
  • 1
SB2055
  • 10,654
  • 29
  • 87
  • 185
  • Both of those examples are `GET` methods. Typically you would only `POST` to a service when you want to `create` whatever it is your sending. – Darren Wainwright Jun 18 '13 at 19:48
  • The first answer to the other question you link to seems to offer a suggestion for your multi-param concern. Why not GET /users/param1,param2,param3,param4? – Chris Farmer Jun 18 '13 at 19:50
  • @user2453734 "because you don't have to post information to acquire information" - what's wrong with this? How is this any more costly than using GET, other than the extra letter in the HTTP verb? – SB2055 Jun 18 '13 at 19:53
  • @ChrisFarmer - because frankly I want to keep my url clean-looking and don't want to deal with the headache of encoding stuff into the URI – SB2055 Jun 18 '13 at 19:55
  • @Darren - updated my post to clarify. Again, "typically" is not a notable reason... I'm looking for actual technical / tangible consequences that might be seen by breaking this convention – SB2055 Jun 18 '13 at 19:56
  • I can see that, but if you happen to have well-defined parameters, it's not a lot of "encoding." Maybe you'd get better suggestions if you provided more context around the type of data you're trying to use as params here. – Chris Farmer Jun 18 '13 at 19:57
  • And I'd venture to say that yes, it's RESTful religiosity that suggests you shouldn't use a POST for this case. – Chris Farmer Jun 18 '13 at 19:59
  • @user2453734 IMHO testing with a browser in many cases is a really poor practice. Browser send a mismash of accept headers. They do heuristic based caching. They magically request resources like favicon.ico without being asked to. They are useless for anything but the most standard media types. Testing auth headers with browsers is a major pain. I would suggest to use a proper HTTPClient like Fiddler or Curl. They handle doing POSTs just fine. – Darrel Miller Jun 18 '13 at 21:50
  • @DarrelMiller I've been using POSTMan in chrome, it rocks. I'll never use fiddler again. – SB2055 Jun 18 '13 at 22:00
  • @user2453734 - thanks for the input - that helps a lot. – SB2055 Jun 18 '13 at 22:02
  • @DarrelMiller i would agree with you but Browsers are the evil of all evils essentially. That is why you always test in them. When i think rest for some reason i always think web application that is why a browser came to mind. –  Jun 18 '13 at 22:15
  • @user2453734 However, 90% of the time API calls from a browser are done using XHR/Jquery which behaves quite differently than requests made by putting a URI in the address bar. – Darrel Miller Jun 18 '13 at 22:21
  • @DarrelMiller and 90% of developers that leverage an API will put the URI into an address bar first to see what it is they are getting for a response to know what they have to parse/expect as a response. Which is what i meant by testing in a browser. Your point is valid, when testing your own code you probably should not use a browser. –  Jun 18 '13 at 22:36

1 Answers1

6

You can use POST to do this. The HTTP spec does not prohibit it.

By using GET you are more accurately representing the characteristics of the request. If you use POST, an intermediary cannot tell that you are performing a safe, idempotent request, even though you are. That may limit the benefits you get from certain intermediaries. You will not be able to take advantage of a cached response by using POST.

If you feel the loss of those benefits do not outweigh the benefits you see to having a cleaner URI, then go-ahead and use POST.

I would suggest that you do not make a habit of using POST over GET for no valid reason, but where sending a body is useful, then do it.

Also realize that if 6 months down the road, you really wish you could cache the response to the search, then you can always change the server response to be a redirect where the client redirects with a GET that has the parameter encoded in the Location URI and then you can take advantage of cached results.

The important thing is you MUST NEVER use a Http method that conveys semantics that are not true. i.e. Never use a GET to do something unsafe. Never use PUT to do something that is not idempotent. However, POST does not constrain the request in anyway, so you could always use POST. Just be aware that intermediaries can't do much to help with POSTs.

Darrel Miller
  • 129,370
  • 30
  • 183
  • 235
  • Thanks Darrel. Can you point me to some kind of documented measure of how GET performs better than POST due to caching? I've been searching and can't find any formal studies / latency metrics or anything. I'm curious about what kind of performance potential I'm losing out on here. – SB2055 Jun 18 '13 at 21:59
  • @SB2055 There is no perf difference in the actual GET vs POST request, however, if you use GET and your responses have valid cache-control headers, then you would be able to take advantage of HTTP caching and potentially could achieve huge perf increases. How useful caching is depends completely on the nature of your search queries. Do many different users perform the same search? Do your searches take a long time? There are lots of factors. – Darrel Miller Jun 18 '13 at 22:06
  • Some APIs use POST to the collection resource as a way to create a resource in the collection, with a server-assigned identifier. Using POST for search here means that you must enforce some other negotiation, like Accept headers, to communicate whether you want a user to be created or a search to be returned. – tilgovi Dec 11 '14 at 00:45
  • 1
    @tilgovi Yes, there are many different uses for POST. The link relation type of the link used to discover the resource being POSTed to can convey the impact of performing the POST operation. – Darrel Miller Dec 11 '14 at 03:20