I noticed that some APIs like twitter API use get methods for everything, so the parameters are passed in the url like this
http://api.twitter.com/1/statuses/user_timeline.json?screen_name=screenname
I have some questions and would appreciate comments or corrections:
I always thought that using GET is not a good idea and that it's better to use POST.
The API I'm coding requires a key, and I don't think it's a good idea to send it in the URL. So is it possible to mix both POST parameters and URL parameters?
Another problem is that I hear URLs have a max length, so I guess that would make GET out of the way, or is there a workaround
The only problem I'm seeing with POST (and which I'm guessing is why a site like twitter went with GET) is that the request can't be made directly from the browser. Correct me if I'm wrong on this.
Updates: Thanks to everyone who's helping me brainstorm this. I have some updates to clarify some of the comments.
When I was talking about not wanting to send the key in the URL, what I meant is that I don't want the key bookmarked if a user were to bookmark a call, not that I don't want the key exposed at all. So I guess from the answers, I could send it in the header field? Any other options?
I want to clarify that when I said POST requests
can't be made from the browser
, I should have said,POST requests can't be made from the url
as inhttp://example.com/api/op.json?param=value
. Sorry, I misspoke, should have been clearer.Re whether it's RESTful or not: I've done RESTful before with an MVC framework that took care of detecting the verbs and the urls ended up looking like
example.com/entry/1
, orexample.com/entry/
and the http verbs are what controlled the operation being performed (create, update, delete, list). I thought, in practical sense, that RESTful was most useful for crud-like data (create entry, get entry, update entry, delete entry, show all entries). So if I don't need crud, do I need REST? My question: if a call simply gives input and returns output, does this API need to be RESTful? The url doesn't look RESTful, so is there something else in the implementation that could make it RESTful?As to the URL size, you commented
but if you're seriously concerned about it you probably should rethink your API. GET requests shouldn't be sending that much data to the server.
So I have this example: user wants to send a large file. On the server, I won't enter the file into the database or save it (so according to standards I'm not "posting" data), but maybe I'm (these are quickly thought examples, so please take them loosely):- (a) reading the metadata of the file and returning it (should that be GET or POST), or
- (b) I'm reading the metadata and modifying the metada on the file and returning the modified file (should that be GET or POST).
- So this is an example of why I might need to send large data. The question is are (a) and (b) considered GET or POST operations? and this is why I was asking about the URL max length
Use GET for reading information, POST for writing information. GET requests shouldn't modify server-side state, while POST requests can safely do so. In general use GET for reads and POST for writes. Your API should probably use a mixture of both, depending on which each specific API call does.
Sending data via POST doesn't add any level of security at all. GET requests are no less insecure than POST requests; they are identical. For transferring private data, use SSL.
You should ideally use an HTTP header like
Authorization
to transmit the key, as this is less likely to be logged by intermediaries, or to be emitted to 3rd party services like bug-trackers.There is no maximum URL length defined by the HTTP standard, though some browsers impose one. This probably doesn't matter when generating GET requests via JavaScript, but if you're seriously concerned about it you probably should rethink your API. GET requests shouldn't be sending that much data to the server.
Your browser can generate POST requests just as easily as GET requests, it's simply harder to submit POST requests via the address bar.
From server point of view, it doesn't matter much what mechanism is used. The only meaningful difference on the server side is that GET requests are usually logged completely (with parameters), while the data of POST requests are usually not logged (but this is not a rule for custom servers, which can log or not log anything).
Moreover, in many cases you can use GET or POST and the server will handle both cases correctly and transparently. Mixing is also possible, and most servers will handle in transparently as well.
GET requests are easier to debug (for web developers), and maybe this was the main reason to use them. I can also think of GET requests to be easier to handle and less resource- consuming (but this depends on how the code is written), cause in GET request everything is passed in header and CRLFCRLF is a request separator (with POST it's necessary to perform additional parsing of the body).
URLs do have max. length (4K to be a common limit, but not mandatory), yes. Some proxies and some servers (and maybe some clients) might be unable to handle larger URLs or have an artificial restriction (to prevent attacks).
I am not sure I understood your idea about "request can't be made directly from the browser". When you fill a web form in browser, it's POSTed to the server (unless JavaScript or AJAX is employed, cause using them you can have a GET request).
The more comprehensive answer is: Please read about REST and HTTP verbs in general.
Here are some short answers to your questions:
It depends on what you're doing.
Yes, it is possible. However, there won't really a big security difference between sending it through the URL versus the request body.
The "workaround" is to use other verbs like POST or PUT for transmitting large amounts of data.
POST requests can be made directly from the browser through the use of a simple HTML
<form>
withmethod="POST"
.Why not support both? It's the most flexible. I have only written one API (multiple versions), and making it support both GET and POST for all variables has come in handy both when implementing the client and debugging. It supports mixing and matching GET and POST. Use $_REQUEST and be done.
As Anon said, Get for retrieving data, post for making changes/sending data, which keeps you in line with the http standard. AFAIK, you can't mix GET/POST params. You can make a post request from a browser by a form, but not by entering a url info the address bar. A key in the get string vs. the post string is not really much different. If the request gets intercepted in transit, the key is compromised either way. If you use a public/private key pair to encrypt the key, than you can resolve that issue. And yes, GET string do have a max length, but so does post, albeit much larger and dependent on your server settings.