tags:

views:

7635

answers:

8

I'm designing an API to go over HTTP and I am wondering if using the HTTP POST command, but with URL query parameters only and no request body, is a good way to go.

Considerations:

  • "Good Web design" requires non-idempotent actions to be sent via POST. This is a non-idempotent action.
  • It is easier to develop and debug this app when the request parameters are present in the URL.
  • The API is not intended for widespread use.
  • It seems like making a POST request with no body will take a bit more work, e.g. a Content-Length: 0 header must be explicitly added.
  • It also seems to me that a POST with no body is a bit counter to most developer's and HTTP frameworks' expectations.

Are there any more pitfalls or advantages to sending parameters on a POST request via the URL query rather than the request body?

Edit: The reason this is under consideration is that the operations are not idempotent and have side effects other than retrieval. See the HTTP spec:

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.

...

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent.

A: 

I think it would probably make more sense to just use a GET instead of POST. POST usually is used when you are posting or providing data to the service.

I have had a similar issue with services that I have written. I was hesitant to use GET since you are really not getting anything but are just looking to perform an operation. I did choose to use the GET since it does make more sense than using a POST with no body. Most Web APIs I have seen use GET regardless of if you are actually 'getting' anything.

Chris Dail
The main reason I want to avoid that is that the operation is not idempotent.
Steven Huwig
+1  A: 

From a programmatic standpoint, for the client it's packaging up parameters and appending them onto the url and conducting a POST vs. a GET. On the server-side, it's evaluating inbound parameters from the querystring instead of the posted bytes. Basically, it's a wash.

Where there could be advantages/disadvantages might be in how specific client platforms work with POST and GET routines in their networking stack, as well as how the web server deals with those requests. Depending on your implementation, one approach may be more efficient than the other. Knowing that would guide your decision here.

Nonetheless, from a programmer's perspective, I prefer allowing either a POST with all parameters in the body, or a GET with all params on the url, and explicitly ignoring url parameters with any POST request. It avoids confusion.

jro
A: 

I agree - it's probably safer to use a GET request if you're just passing data in the URL and not in the body. See this similar question for some additional views on the whole POST+GET concept.

Marc Novakowski
+6  A: 

You want reasons? Here's one:

A web form can't be used to send a request to a page that uses a mix of GET and POST. If you set the form's method to GET, all the parameters are in the query string. If you set the form's method to POST, all the parameters are in the request body.

Source: HTML 4.01 standard, section 17.13 Form Submission

R. Bemrose
That's a decent argument, but I think modern browser's Javascript implementations kind of make it a moot point. I'll think about it though -- it is compelling in a future-proofing kind of way. Just because I'm not using a form for it now doesn't mean I won't want to later.
Steven Huwig
Mixing GET with POST is just a really bad idea - terribly breaking HTTP and for no good reason.
Wahnfrieden
That snippet doesn't appear on the page you linked to
Gareth
@Gareth: It's implicit in the description of the method attribute. You can only set it to get *or* post, not both.
R. Bemrose
Right, but the method attribute just defines how the "form data set" is included in the request. When the `method` is POST, there's no mention of changing the URI in the form's `action`. And any URI can of course already contain a query string part.
Gareth
By the way, I also thought that it wasn't possible to mix GET and POST. I just can't find any justification for that behaviour in the spec, and I don't think that your interpretation matches what's written there
Gareth
+3  A: 

If your action is not idempotent, then you MUST use POST. If you don't, you're just asking for trouble down the line. GET, PUT and DELETE methods are required to be idempotent. Imagine what would happen in your application if the client was pre-fetching every possible GET request for your service -- if this would cause side effects visible to the client, then something's wrong.

I agree that sending a POST with a query string but without a body seems odd, but I think it can be appropriate in some situations.

Think of the query part of a URL as a command to the resource to limit the scope of the current request. Typically, query strings are used to sort or filter a GET request (like ?page=1&sort=title) but I suppose it makes sense on a POST to also limit the scope (perhaps like ?action=delete&id=5).

Don McCaughey
I selected this answer for this particular case, but I think R. Bemrose's argument is compelling for public APIs.
Steven Huwig
I don't think his answer is strictly correct. If you know the URL parameters for your form post when the HTML page is sent to the client, you can tack those URL parameters on to the form's action attribute, otherwise JavaScript can set the URL parameters when the form is submitted.
Don McCaughey
A: 

The REST camp have some guiding principles that we can use to standardize the way we use HTTP verbs. This is helpful when building RESTful API's as you are doing.

In a nutshell: GET should be Read Only i.e. have no effect on server state. POST is used to create a resource on the server. PUT is used to update or create a resource. DELETE is used to delete a resource.

In other words, if your API action changes the server state, REST advises us to use POST/PUT/DELETE, but not GET.

User agents usually understand that doing multiple POSTs is bad and will warn against it, because the intent of POST is to alter server state (eg. pay for goods at checkout), and you probably don't want to do that twice!

Compare to a GET which you can do an often as you like.

saille
The REST camp say you should use HTTP as defined in the HTTP spec. i.e. RFC2616 Nothing more, nothing less.
Darrel Miller
A: 

Does anyone have a good reference for the encoding of key-value pairs in the POST body? Looking for something beyond name1=value1&name2=value2, more along the lines of multiple selections in a select and multiple selected checkboxes in a group.

Thanks, Sherman

Sherman
A: 

I feel a lot more people need to read this, very good info!

Car Transport