HTTP methods: DELETE vs POST - http

Let's say I have a resource called "Session". The client would call PUT to create and begin a new session. When the client is finished with the session, it should no longer be accessible, but should persist for historical/accountability reasons.
To end the session, would it be more appropriate to issue a DELETE request, which would seem semantically closer to the desired effect, or POST, seeing as the resource isn't actually removed permanently?

The question here is: Is the request idempotent? If you execute the same request twice, does it have a side effect? Like when you order an article, executing the order request twice would get you the article twice.
In that case, POST is the method you want. If not, then you want either PUT or DELETE.
As you don't seem to be deleting the session, only altering its state, PUT would be a better method, because it means that the resource is altered, and not deleted, which is the case in your case.
Edit:
If the resource appears to be deleted from the client, DELETE seems more appropriate. How things are implemented in the back doesn't matter for the client.

POST request will be better here as you don't actually delete the session. POST requests are often used to change state of an object. It is your case I think.

Related

when I must use PUT (or another method) request over POST?

apart from GET method,
we can make POST implement the request typically as any other http method, so why we should use other methods rather than POST?
POST='delete some data from this resource'
also we can make the POST idempotence by ignoring the subsequent requests (ignoring that PUT can create a new resource)
Well, actually you could also use only GET and DELETE requests for everything. It's only the question how the backend handles these specific request types.
If you want to follow the rules, then you would usually develop so that you provide conformity to usual standards (PUT for creation, DELETE for deletion) and so on.
Can somehow be compared to response status codes. Of course I could return the response code 200 and 201 for "Unauthorized", as response codes can be defined individually. But that's against every standard and should not be done.

how GET method is idempotent

How GET method is idempotent and POST is not. we are using it in form submission, if we submitting it twice it will re-submitting the form data's. And why we are not using GET for order placing or purchasing products for instance when it is idempotent.
An idempotent HTTP method is a HTTP method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. Again, this only applies to the result, not the resource itself.
a=10; //This is idempotent: no matter how many times we execute this statement, a will always be 4.
a++; //This is not idempotent. Executing this 10 times will result in a different outcome as when running 5 times.
Now, coming to your query.
If we use GET method for order placing/purchasing products, the order will be placed no matter the product is gone out of stock. In contrast if you use the to POST method the result will be different for each new request made for purchasing product.
Below example is not idempotent because for every new request the outcome will be different
https://accounts.google.com/Login#identifier
The GET method should be used to send the information from the browser to the server in the URL. Below is an example usage of GET method.
http://www.google.co.in/search?q=cristiano+ronaldo
Below is the answer to your query in the comments:
When users revisit a page that resulted from a form submission, they might be presented with the page from their history stack (which they had probably intended), or they might be told that the page has now expired. Typical user response to the latter is to hit Reload.
This is harmless if the request is idempotent, which the form author signals to the browser by specifying the GET method.
Browsers typically will (indeed "should") caution their users if they are about to resubmit a POST request, in the belief that this is going to cause a further "permanent change in the state of the universe", e.g. ordering another Mercedes-Benz against their credit card or whatever. If users get so accustomed to this happening when they try to reload a harmless idempotent request, then sooner or later it's going to bite them when they casually [OK] the request.
Now, while implementing those two methods GET and POST, a developer should consider the security issues and write the code in the particular method. Any code can be written in both the methods considering all the limits of GET method(size of url etc.), But this is not a good practice.
GET -> for information retrieval.(If you want to read data without changing state)
POST -> for information creation/updation/deletion.

How to create a RESTful object with server calculated fields

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.

Okay to POST with an empty body, pass data in the response?

I want a client to be able to request (via HTTP) whichever document is at the head of a server's output queue, with the understanding that if retrieval is successful, the document will then automatically be deleted from the queue. There is never more than one client per server, but the client could be multithreaded. There is no random access to the queue; only the head item can be retrieved (and deleted). I have not found this scenario discussed either here or elsewhere on the web. Here are the various approaches I can think of:
(1) The client could send a GET request. But GET is not supposed to have side effects, so this doesn't seem like a good idea.
(2) The client could send two requests, a GET to retrieve the document at the head of the queue and a DELETE (with an empty or ignorable URL) to delete the document at the head of the queue. But this requires two calls, which could cause various problems, especially if more than one thread/process in the client is trying to retrieve files.
(3) The client could send a POST request with an empty body; if there is a document at the head of the queue, the server will return a response whose body contains the document, and will also delete the document from the queue. This is somewhat counterintuitive in that it doesn't match the mental model of posting data and receiving a simple return code, but otherwise I like it. I'm not worried about the response getting lost in transit and the document going missing; I expect the connection to be safe enough to prevent this.
It would be nice if there were another HTTP method to handle this situation, but since there isn't, I think (3) is the best approach. Agree? Disagree?
UPDATE: Added (4) after reading Dan675's post below.
(4) The client could send a DELETE request, to which the server could send a response with the document in the body (and delete the document from the queue, of course). Again, this is slightly counterintuitive (you don't usually say "delete the item on top of the stack for me, please" when you want to retrieve it), but would work.
It should be done in two calls the first to GET it then one to DELETE it.
If the delete succeeds then the clients request is valid otherwise just treat it as if the whole request failed and try to get what's on the top of the queue again. This will cause some additional overhead due to failed requests but I would not recommend doing either of the other options.
I guess another way of doing this would be to first maybe do a PUT to mark the top most item as 'reserved' in some way then do a GET and DELETE. In doing it this way it may be possible to traverse this server side queue and look for the top-most item that is not 'reserved'.

HTTP method to represent "fire and forget" actions in RESTful service

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).

Resources