I have an object:
Account
{
Id,
Name,
CurrentBalance
}
Id is an immutable key, Name is a mutable string, and CurrentBalance is calculated from all of the transactions associated with the account.
I am stuck on the fact that GET \Accounts\{Id} will not be idempotent because changes to a transaction will cause a change in CurrentBalance. Should I remove this field from the object and make a request like
POST \Accounts\{Id}\CurrentBalance
But now I have to make multiple calls to the server to get the CurrentBalance of all objects:
GET \Accounts
POST \Accounts\{Id1}\CurrentBalance
POST \Accounts\{Id2}\CurrentBalance
POST \Accounts\{Id3}\CurrentBalance
....
I guess I am just looking to see if there is already a standard way to handle this that I am missing?
UPDATE
Part 2 if the original object is ok via GET. My only way to update the Account.Name is via a PATCH as I cannot allow an update to CurrentBalance, correct?
NOTE
I realize I could put this on the client to have to get all transactions and calculate it, but I would prefer to do this on the server for multiple reasons
Idempotency does not mean that you must always get the same response back.
Consider the resource /TodaysWeather. It would be pretty useless if it always returned the same value.
Idempotency simply states that if a client makes the same request multiple times instead of just once, the impact on the system (from the client's perspective) will be the same.
I just re-read the HTTP specs and realized that if I want to be truly RESTful I have to make multiple calls because GET has to be safe.
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.
I am not deleting this question because I think it could help others in the future, but if the majority disagree I will delete it
If it's important that you're able to PUT some data, then immediately retrieve the same data via GET, then you could simply treat it as a different resource entirely, e.g.:
# Change an account name
PUT \Accounts\{id}
# Get accounts/names/balances
GET \AccountDetails
# Get balance of an account
GET \AccountDetails\{id}\CurrentBalance
However, there's really no good reason to go through the trouble of doing that. Your PUT is idempotent as long as making the same request multiple times doesn't change the state of the system. Not changing the system's state if some spurious value is submitted is the correct behavior. In fact, if someone does try a PUT including CurrentBalance, you might want to return a 400 (Bad Request) status explaining that CurrentBalance can't be updated.
This question already has answers here:
When should I use GET or POST method? What's the difference between them?
(15 answers)
Closed 9 years ago.
I've only recently been getting involved with PHP/AJAX/jQuery and it seems to me that an important part of these technologies is that of POST and GET.
First, what is the difference between POST and GET? Through experimenting, I know that GET appends the returning variables and their values to the URL string
website.example/directory/index.php?name=YourName&bday=YourBday
but POST doesn't.
So, is this the only difference or are there specific rules or conventions for using one or the other?
Second, I've also seen POST and GET outside of PHP: also in AJAX and jQuery. How do POST and GET differ between these 3? Are they the same idea, same functionality, just utilized differently?
GET and POST are two different types of HTTP requests.
According to Wikipedia:
GET requests a representation of the specified resource. Note that GET should not be used for operations that cause side-effects, such as using it for taking actions in web applications. One reason for this is that GET may be used arbitrarily by robots or crawlers, which should not need to consider the side effects that a request should cause.
and
POST submits data to be processed (e.g., from an HTML form) to the identified resource. The data is included in the body of the request. This may result in the creation of a new resource or the updates of existing resources or both.
So essentially GET is used to retrieve remote data, and POST is used to insert/update remote data.
HTTP/1.1 specification (RFC 2616) section 9 Method Definitions contains more information on GET and POST as well as the other HTTP methods, if you are interested.
In addition to explaining the intended uses of each method, the spec also provides at least one practical reason for why GET should only be used to retrieve data:
Authors of services which use the HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data, because this will cause this data to be encoded in the Request-URI. Many existing servers, proxies, and user agents will log the request URI in some place where it might be visible to third parties. Servers can use POST-based form submission instead
Finally, an important consideration when using GET for AJAX requests is that some browsers - IE in particular - will cache the results of a GET request. So if you, for example, poll using the same GET request you will always get back the same results, even if the data you are querying is being updated server-side. One way to alleviate this problem is to make the URL unique for each request by appending a timestamp.
A POST, unlike a GET, typically has relevant information in the body of the request. (A GET should not have a body, so aside from cookies, the only place to pass info is in the URL.) Besides keeping the URL relatively cleaner, POST also lets you send much more information (as URLs are limited in length, for all practical purposes), and lets you send just about any type of data (file upload forms, for example, can't use GET -- they have to use POST plus a special content type/encoding).
Aside from that, a POST connotes that the request will change something, and shouldn't be redone willy-nilly. That's why you sometimes see your browser asking you if you want to resubmit form data when you hit the "back" button.
GET, on the other hand, should be idempotent -- meaning you could do it a million times and the server will do the same thing (and show basically the same result) each and every time.
Whilst not a description of the differences, below are a couple of things to think about when choosing the correct method.
GET requests can get cached by the browser which can be a problem (or benefit) when using ajax.
GET requests expose parameters to users (POST does as well but they are less visible).
POST can pass much more information to the server and can be of almost any length.
POST and GET are two HTTP request methods. GET is usually intended to retrieve some data, and is expected to be idempotent (repeating the query does not have any side-effects) and can only send limited amounts of parameter data to the server. GET requests are often cached by default by some browsers if you are not careful.
POST is intended for changing the server state. It carries more data, and repeating the query is allowed (and often expected) to have side-effects such as creating two messages instead of one.
If you are working RESTfully, GET should be used for requests where you are only getting data, and POST should be used for requests where you are making something happen.
Some examples:
GET the page showing a particular SO question
POST a comment
Send a POST request by clicking the "Add to cart" button.
With POST you can also do multipart mime encoding which means you can attach files as well. Also if you are using post variables across navigation of pages, the user will get a warning asking if they want to resubmit the post parameter. Typically they look the same in an HTTP request, but you should just stick to POST if you need to "POST" something TO a server and "GET" if you need to GET something FROM a server as that's the way they were intended.
The only "big" difference between POST & GET (when using them with AJAX) is since GET is URL provided, they are limited in ther length (since URL arent infinite in length).
Thinking about REST, it's relatively easy to map HTTP methods to CRUD actions: POST for create, GET for read, etc. But what about "fire and forget" actions? What HTTP method would best represent a fire and forget action such as triggering a batch job (in which no response is sent back to the caller)?
POST would spring to mind, but I think GET is also an appropriate method because 99% of the time you only supply a bunch of parameters to these types of actions. What do you think?
POST would spring to mind, but I think GET is a more appropriate method because 99% of the time you only supply a bunch of parameters to these types of actions. What do you think?
External State
I think that the number of parameters you use has nothing to do with the verb you use. The key issue is are you changing externally visible state?
BatchJob Resources
In your example, if the batch job does not affect the externally visible state of any object then you could implement it as a batch job. However you could model your batch job as a resource with an associated resource container.
You could use a Post to create a new BatchJob resource and allow the user to do a GET to see the progress of the job so far. You could do a GET on the resource container to list all of the running batch jobs, possibly calling DELETE to kill one.
You should use POST if your request modifies data, and GET if it only reads it.
Since your request is "fire and forget", I guess that it's modifying data, so use POST.
I think in the general case we might well supply various payload parameters, and these plausibly might exceed what's possible with GET, so POST is quite reasonable - the action of starting a job doesn't to me fit well with GET sematics.
One thought, might not the action actually return a response:
a). No, sir, that's an impossible request we can't start your job.
b). Understood, your job reference is 93.
If you're concerned at that level, perhaps HEAD is the HTTP method you want; it's identical to GET, with the stipulation that the response body is empty. That sounds to me spot-on to what you're asking for?
I'm bringing this question back from the dead to offer a different point of view.
Now that CORS is prevalent, the choice between using GET or POST becomes a matter of if you want anyone who knows your API URI to be able to trigger the batch job (GET), or if you want to restrict the origin of the request to prevent any Joe with a computer from triggering the job (POST).
If I have a HTTP based RESTful service and I want to POST a search resource and use the PRG pattern for returning the URL to the search-result resource, I have to persist the search-result resource on the server.
Is this a good idea?
If I do persist the search-result resource how long is it persisted for?
Can I control this by a HTTP header of some kind?
Cheers
AWC
I don't think REST or HTTP can provide you with any guidance on this. How long the search results should persist for is purely a function of how big they are, how expensive they are to calculate, how dynamic the data is, how often the same results are requested and how much money do you want to spend on hardware to get performance.
Having said that, you could use 410 Gone to interesting effect. After a period of time you could throw away the results but keep the query parameters and saved resource url. If you get a request to that URL after the results have been thrown away, you could return 410 Gone with the query parameters in the body. The client could be prompted to decide if they want to re-issue the query.
Depending on the data, you could even hide the re-query from the client. However, depending on the type of data being returned that could be misleading to the client.
You'll notice that when you do a google search, the page with the results actually has your search in the url, and if you inspect the form on google's home page that the form is actually set to GET. So in a search scenario it is actually common to just use a single get request and not a post request, since you are using it to "GET" search results based on a particular query.
A "POST" event might be more useful when you are "POST"ing data, like when you post something on a message board. You are adding data to a database, message board, user profile, etc.
If getting the search result is a heavy tax on your system, then you might want to look into a way of caching the results based on the search term, so that whenever a get request is made for that term, the results are easier to pull together.
Ok, I know the difference in purpose. GET is to get some data. Make a request and get data back. POST should be used for CRUD operations other than read I believe. But when it comes down to it, does the server really care if it's receiving a GET vs. POST in the end?
According to the HTTP RFC, GET should not have any side-effects, while POST may have side-effects.
The most basic example of this is that GET is not appropriate for anything like a purchase-transaction or posting an article to a blog, while POST is appropriate for actions-that-have-consequences.
By the RFC, you can hold a user responsible for actions done by POST (such as a purchase), but not for GET actions. 'Bots always use GET for this reason.
From the RFC 2616, 9.1.1:
9.1.1 Safe Methods
Implementors should be aware that the
software represents the user in
their interactions over the Internet,
and should be careful to allow the
user to be aware of any actions they
might take which may have an
unexpected significance to themselves
or others.
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.
Naturally, it is not possible to
ensure that the server does not
generate side-effects as a result of
performing a GET request; in fact,
some dynamic resources consider that a
feature. The important distinction
here is that the user did not request
the side-effects, so therefore
cannot be held accountable for them.
It does if a search engine is crawling the page, since they will be making GET requests but not POST. Say you have a link on your page:
http://www.example.com/items.aspx?id=5&mode=delete
Without some sort of authorization check performed before the delete, it's possible that Googlebot could come in and delete items from your page.
Since you're the one writing the server software (presumably), then it cares if you tell it to care. If you handle POST and GET data identically, then no, it doesn't.
However, the browser definitely cares. Refreshing or clicking back to a page you got as a response to a POST pops up the little "Are you sure you want to submit data again" prompt, for example.
GET has data limit restrictions based on the sending browser:
The spec for URL length does not dictate a minimum or maximum URL length, but implementation varies by browser. On Windows: Opera supports ~4050 characters, IE 4.0+ supports exactly 2083 characters, Netscape 3 -> 4.78 support up to 8192 characters before causing errors on shut-down, and Netscape 6 supports ~2000 before causing errors on start-up
If you use a GET request to alter back-end state, you run the risk of bad things happening if a webcrawler of some kind traverses your site. Back when wikis first became popular, there were horror stories of whole sites being deleted because the "delete page" function was implemented as a GET request, with disastrous results when the Googlebot came knocking...
"Use GET if: The interaction is more like a question (i.e., it is a safe operation such as a query, read operation, or lookup)."
"Use POST if: The interaction is more like an order, or the interaction changes the state of the resource in a way that the user would perceive (e.g., a subscription to a service), or the user be held accountable for the results of the interaction."
source
You be aware of a few subtle security differences. See my question
GET versus POST in terms of security?
Essentially the important thing to remember is that GET will go into the browser history and will be transmitted through proxies in plain text, so you don't want any sensitive information, like a password in a GET.
Obvious maybe, but worth mentioning.
By HTTP specifications, GET is safe and idempotent and POST is neither. What this means is that a GET request can be repeated multiple times without causing side effects.
Even if your server doesn't care (and this is unlikely), there may be intermediate agents between your client and the server, all of whom have this expectation. For example proxies to cache data at your ISP or other providers for improved performance. THe same expectation is true for accelerators, for example, a prefetching plugin for your browser.
Thus a GET request can be cached (based on certain parameters), and if it fails, it can be automatically repeated without any expecation of harmful effects. So, really your server should strive to fulfill this contract.
On the other hand, POST is not safe, not idempotent and every agent knows not to cache the results of a POST request, or retry a POST request automatically. So, for example, a credit card transaction would never, ever be a GET request (you don't want accounts being debited multiple times because of network errors, etc).
That's a very basic take on this. For more information, you might consider the "RESTful Web Services" book by Ruby and Richardson (O'Reilly press).
For a quick take on the topic of REST, consider this post:
http://www.25hoursaday.com/weblog/2008/08/17/ExplainingRESTToDamienKatz.aspx
The funny thing is that most people debate the merits of PUT v POST. The GET v POST issue is, and always has been, very well settled. Ignore it at your own peril.
GET has limitations on the browser side. For instance, some browsers limit the length of GET requests.
I think a more appropriate answer, is you can pretty much do the same things with both. It is not so much a matter of preference, however, but a matter of correct usage. I would recommend you use you GETs and POSTs how they were intended to be used.
Technically, no. All GET does is post the stuff in the first line of the HTTP request, and POST posts stuff in the body.
However, how the "web infrastructure" treats the differences makes a world of difference. We could write a whole book about it. However, I'll give you some "best practises":
Use "POST" for when your HTTP request would change something "concrete" inside the web server. Ie, you're editing a page, making a new record, and so on. POSTS are less likely to be cached, or treated as something that's "repeatable without side-effects"
Use "GET" for when you want to "look at an object". Now, such a look might change something "behind the scenes" in terms of caching or record keeping, but it shouldn't change anything "substantial". Ie, I could repeat my GET over and over and nothing bad would happen, except for inflated hit counts. GETs should be easily bookmarkable, so a user can go back to that same object later on.
The parameters to the GET (the stuff after the ?, traditionally) should be considered "attributes to the view" or "what to view" and so on. Again, it shouldn't actually change anything: use POST for that.
And, a final word, when you POST something (for example, you're creating a new comment), have the processing for the post issue a 302 to "redirect" the user to a new URL that views that object. Ie, a POST processes the information, then redirects the browser to a GET statement to view the new state. Displaying information as a result of a POST can also cause problems. Doing the redirection is often used, and makes things work better.
Should the user be able to bookmark the resulting page? Another thing to think about is some browsers/servers incorrectly limit the GET URI length.
Edit: corrected char length restriction note - thanks ars!
It depends on the software at the server end. Some libraries, like CGI.pm in perl handles both by default. But there are situations where you more or less have to use POST instead of GET, at least for pushing data to the server. Large amounts of data (where the corresponding GET url would become too long), binary data (to avoid lots of encoding/decoding trouble), multipart files, non-parsed headers (for continuous updates pre-AJAX style...) and similar.
The server technically couldn't care one way or the other about what kind of request it receives. It will blindly execute any request coming across the wire.
Which is the problem. If you have an action that destroys or modifies data in a GET action, Google will tear your site up as it crawls through indexing.
The server usually doesn't care. But it's mostly for following good practices, as you mentioned. The client side also matter - as mentioned you cannot bookmark a POST'd page usually, and some browsers have limits on the length of the URL for really long GET queries.
Since GET is intended for specifying resource you wanna get, depending on exact software on the server side, the web server (or the load balancer in front of it) may have a size limit on GET requests to prevent Denial Of Service attacks...
Be aware that browsers may cache GET requests but will generally not cache POST requests.
Yes, it does matter. GET and POST are quite different, really.
You are right in that normally, GET is for "getting" data from the server and displaying a page, while POST is for "posting" data back to the server. Internally, your scripts get the same data whether it's GET or POST, so no, the server doesn't really care.
The main difference is GET parameters are specified in URLs, while POST is not. This is why POST is used for signup and login forms - you don't want your password in a URL. Similarly, if you're viewing different pages or displaying a specific view of some data, you normally want a unique URL.
It really does matter. I have gathered like 11 things you should know abut them.
11 things you should know about GET vs POST
No, they shouldn't except for #jbruce2112 answer and uploading files require POST.