Question

What's the rule of thumb for passing data in a REST URL in the query string vs. the body of a request?

Ie: You're creating a service to add hockey players. You could go with:

PUT /players 
{ "name": Gretzky }

or

PUT /players?name=Gretzky

If you're passing a lot of data, you would need to go with option #1 as there is a limit on the URL length. But other than this, why not just use the query string to pass data?


Update: Removed comment that you could test option #2 in a browser. Realized (duh) that you can only do GET-s in your browser.

Was it helpful?

Solution

Based on HTTP's definition of PUT, your first request is overwriting the list of players with a new list that contains just one player name. It is not adding to the list of players.

The second option does not really make much sense to me. Doing PUT without a body is not really consistent with the meaning of PUT.

Considering that one of the standard definitions of POST is to append to an existing resource, I'm not sure why you wouldn't do

POST /players 
{ "name": Gretzky }

If you are sure that all you player names are going to be unique then you could use PUT like this:

PUT /player/Gretzky
{ "name": Gretzky }

When you decide to do REST on HTTP you are agreeing to use HTTP in the way that is defined in RFC2616. That's what the uniform interface constraint means. And just to be pedantic, there is no such thing as a REST URL and you can't test either option in a browser because without javascript, you can't do a PUT in a browser.

OTHER TIPS

Option #1 is fine, though probably overkill. Option #1 is not fine because it's not idempotent.

Option #2 is a BAD idea. That would be misusing PUT. PUT should be used primarily when your request data payload is an opaque block of data, usually either large or hierarchical. Smaller, non-hierarchical payloads make more sense as POST.

Also, try to avoid changing state via query parameters. There's nothing technically dangerous about that if it's not a GET request, but it's not really RESTful.

In this case, what you should be doing is:

POST /players HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 12

name=Gretsky

This should return a 201 Created response. (There is an exception to this: If you don't create the resource immediately, and it might be rejected at a later time, use 202 Accepted instead.)

Writing a REST web service that uses more of HTTP than POST and GET should only be done after having read the HTTP specification. (It's a very useful read.) That rule is a bit looser if you're using a framework that makes all the decisions for you.

My understanding of REST operations is that the URL uniquely identifies the resource, while the body of the request contains the representation of the resource. Given that, it's questionable whether either of your options are truly RESTful.

The first would be, assuming that the resource is named "Players" and a GET on that resource returns a list of players (I won't get into the question of whether that GET returns other resource URLs or not ... Fielding would say that it should, with individual requests to get the resource data).

The second would be, assuming that the request body contained information keyed by name "Gretsky". However, that requires you to generate the keys externally.

The url used should identify the resource in the body, either by path components or query parameters, though I would prefer path components for something like a name or id. The body should be a representation; the one you PUT should the same or similar as what you GET from the same url (or can get, the in case of multiple formats)

Example #1 is inappropriate because you are sending a representation for a single player to a url for all players. POST would be more appropriate in this case.

Example #2 would be slightly inappropriate if extended to all fields because you would then be sending representation data in the url.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top