Is locking a document with a GET request evil - http

I'm trying to implement pessimistic concurrency for a web application and I am having some issues on how I should proceed to lock my document. At the moment, I'm being told that to lock a document, it should be a POST action instead of locking the document from a GET action.
I understand that a GET method should be idempotent and only return the document without any side effect. I also read about conditionnal and partial GET but that does not seems to fix my issue since none of the header fields seems usable for pessimistic concurrency.
On the other end, a POST method should send a document that the server should use to replace an existing one or to create it from if that document did not exist on the server. I find it perplexing to obtain my document on a POST action.
I am quite confused about this. I honestly do not know how to proceed. Is locking the document for other readers from a GET request considered a side effect.
EDIT:
I know I will get lynched for that but I have any other idea even tho it feels wrong.
First step is checking with a get request if the document is locked. Depending on the answer of that request, three things can happen.
If it's unlocked, I submit a form to execute a POST action to get the document. Why? So that someone that hit refresh doesn't loose control of the document and is not told that the document is locked since there is a hidden token that verify if it's the same lock.
If it's locked by another user, I'm telling the user that it can't access it right now.
If the user tried to opened a second time the same document, I need to ask him if he want to take control of said document in that particular tab. If he does, I get the document and create a new lock to invalidate the previous one.

Is locking the document for other readers from a GET request considered a side effect?
GET is a safe method and shouldn't be used for locking a resource. From the RFC 7231:
4.2.1. Safe Methods
Request methods are considered "safe" if their defined semantics are
essentially read-only; i.e., the client does not request, and does
not expect, any state change on the origin server as a result of
applying a safe method to a target resource. [...]
Pessimitic locking could be handled with different requests for retrieving a representation of the resource and creating a lock. See the examples below.
Request a representation of the resource:
GET /document/1 HTTP/1.1
Host: example.com
Create a lock:
POST /document/1/lock HTTP/1.1
Host: example.com
Modify the resource:
PUT /document/1 HTTP/1.1
Host: example.com
Content-Type: text/plain
This is the new content of the document.
Release the lock:
DELETE /document/1/lock HTTP/1.1
Host: example.com
Attempts to modify or retrieve a representation of a locked resource could return 409 indicating that the request could not be completed due to a conflict with the current state of the target resource. The server also should generate a payload that includes enough information for a user to recognize the source of the conflict.
If optimistic locking suits you, consider conditional requests:
Conditional requests are HTTP requests that include one or
more header fields indicating a precondition to be tested before
applying the method semantics to the target resource. [...]
Conditional GET requests are the most efficient mechanism for HTTP
cache updates. Conditionals can also be applied to
state-changing methods, such as PUT and DELETE, to prevent the "lost
update" problem: one client accidentally overwriting the work of
another client that has been acting in parallel. [...]
Check the RFC 7232 for further details.

Related

Is it correct to respond with 304 to non-conditional PUTs if no update was necessary?

I have a somewhat-RESTful API with a resource where I unconditionally PUT data to ensure it exists and is up-to-date. E.g.:
PUT /users/username/ HTTP/1.0
Content-Type: text/json
{"email": "username#example.org"}
Performing such requests, I don't care if user existed or not, I want the "create-or-update" logic. If user doesn't exist, it will be created (and I'll respond with 201 Created). If it already exists, API service will ensure its notion of user (email address) is up-to-date.
However, I wonder if it's semantically correct (with respect to the standards) to respond with 304 Not Modified (rather than the usual 200 OK) to non-conditional requests (without any If-* headers), in case the resource was already in that exact state and no change were performed.
So, my question is whenever standards allow such behavior, permit but discourage it, or prohibit it?
(Note: Adding ETags or modification times would be only a nuisance at the moment, and raise server- and client-side complexity. I don't want client-side to keep any extra state information at the moment.)
No, it would not be correct (see https://greenbytes.de/tech/webdav/rfc7232.html#status.304).

REST HTTP status code for "success, and thus you no longer have access"

My RESTful service includes a resource representing an item ACL. To update this ACL, a client does a PUT request with the new ACL as its entity. On success, the PUT response entity contains the sanitized, canonical version of the new ACL.
In most cases, the HTTP response status code is fairly obvious. 200 on success, 403 if the user isn't permitted to edit the ACL, 400 if the new ACL is malformed, 404 if they try to set an ACL on a nonexistent item, 412 if the If-Match header doesn't match, and the like.
There is one case, however, where the correct HTTP status code isn't obvious. What if the authenticated user uses PUT to remove themselves from the ACL? We need to indicate that the request has succeeded but that they no longer have access to the resource.
I've considered returning 200 with the new ACL in the PUT entity, but this lacks any indication that they no longer have the ability to GET the resource. I've considered directly returning 403, but this doesn't indicate that the PUT was successful. I've considered returning 303 with the Location pointing back to the same resource (where a subsequent GET will give a 403), but this seems like a misuse of 303 given that the resource hasn't moved.
So what's the right REST HTTP status code for "success, and thus you no longer have access"?
200 is the appropriate response, because it indicates success (as any 2xx code implies). You may distinguish the user's lack of permission in the response (or, if you don't wish to, 204 is fine). Status codes make no contract that future requests will return the same code: a 200 response to the PUT does not mean a subsequent GET can't return 403. In general, servers should never try to tell clients what will happen if they issue a particular request. HTTP clients should almost always leap before they look and be prepared to handle almost any response code.
You should read the updated description of the PUT method in httpbis; it discusses not only the use of 200/204 but indicates on a careful reading that returning a transformed representation in immediate response to the PUT is not appropriate; instead, use an ETag or Last-Modified header to indicate whether the entity the client sent was transformed or not. If it was, the client should issue a subsequent GET rather than expecting the new representation to be sent in response to the PUT, if for no other reason than to update any caches along the way (because the response to a PUT is not cacheable). Section 6.3.1 agrees: the response to a PUT should represent the status of the action, not the resource itself. Note also that, for a new ACL, you MUST return 201, not 200.
You're confusing two semantic ideas, and trying to combine them into a single response code.
The first: That you successfully created an ACL at the location that you were attempting to. The correct semantic response (in either a RESTful or non-RESTful scenario) is a 201 Created. From the RFC: "The request has been fulfilled and resulted in a new resource being created."
The second: That the user who executed the PUT does not have access to this resource any more. This is a transient idea - what if the ACL is updated, or something changes before the next request? The idea that a user does not have access to a resource of any kind (and this includes an ACL resource) only matters for the scope of that request. Before the next request is executed, something could change. On a single request where a user does not have access to something you should return a 403 Forbidden.
Your PUT method should return a 201. If the client is worried about whether it has access any more, it should make a subsequent request to determine it's status.
You might want to take a look at HTTP response code "204 No Content" (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html), indicating that the "server has fulfilled the request [to be removed from the ACL] but does not need to return an entity-body, and might want to return updated metainformation" (here, as a result of the successful removal). Although you're not allowed to return a message body with 204, you can return entity headers indicating changes to the user's access to the resource. I got the idea from Amazon S3 - they return a 204 on a successful DELETE request (http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html), which seems to resemble your situation since by removing yourself from an ACL, you've blocked access to that resource in the future.
Very interesting question :-) This is why I love REST, sometimes it might get you crazy. Reading w3 http status code definitions I would choose (this of course is just my humble opinion) one of those:
202 Accepted - since this mean "well yes I got your request, I will process it but come back later and see what happens" - and when the user comes back later she'll get a 403(which should be expected behavior)
205 Reset Content - "Yep, I understood you want to remove yourself please make a new request, when you come back you'll get 403"
On the other hand (just popped-up in my mind), why should you introduce a separate logic and differentiate that case and not using 200 ? Is this rest going to be used from some client application that has an UI? And the user of the rest should show a pop-up to the end-user "Are you sure you want to remove yourself from the ACL?" well here the case can be handled if your rest returns 200 and just show a pop-up "Are you sure you want to remove user with name from the ACL?", no need to differentiate the two cases. If this rest will be used for some service-to-service communication(i.e. invoked only from another program) again why should you differentiate the cases here the program wouldn't care which user will be removed from the ACL.
Hope that helps.

Why do we need HTTP GET? Is there anything that can't be achieved by HTTP POST?

As far as I know what GET can do, the same can be achieved by POST. So why was GET required in first place while defining HTTP protocol. If GET is only for fetching the resource, people can still update resources by sending the parameters values in URL. Why this loophole? Or the guy who did the coding on server side to update the resource on GET request has written a bad code?
HTTP specified different methods for different purposes. The GET method is intended to be used to “retrieve whatever information (in the form of an entity) is identified by the Request-URI”. Especially, it is intended to be a safe and idempotent method. That means a GET request should not have side effects (i.e. changing data):
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.
And sending an identical request multiple times results in the same as sending it just once:
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.
Practically, no browser implements POSTing by clicking links (without intercepting the click event in JavaScript), nor bookmarking POST data. Furthermore, semantically POST and GET serve different purposes. One is for POSTing data to an application, the other is for GETting data from the application. These semantics have practical implications, but they also have theoretical design implications that speak to the quality of your application's design: an application that doesn't handle GET differently from POST probably has a great deal of security problems and workflow bugs.
From RFC 2616:
9.3 GET
The GET method means retrieve whatever
information (in the form of an entity)
is identified by the Request-URI. If
the Request-URI refers to a
data-producing process, it is the
produced data which shall be returned
as the entity in the response and not
the source text of the process, unless
that text happens to be the output of
the process.
The semantics of the GET method change
to a "conditional GET" if the request
message includes an If-Modified-Since,
If-Unmodified-Since, If-Match,
If-None-Match, or If-Range header
field. A conditional GET method
requests that the entity be
transferred only under the
circumstances described by the
conditional header field(s). The
conditional GET method is intended to
reduce unnecessary network usage by
allowing cached entities to be
refreshed without requiring multiple
requests or transferring data already
held by the client.
The semantics of the GET method change
to a "partial GET" if the request
message includes a Range header field.
A partial GET requests that only part
of the entity be transferred, as
described in section 14.35. The
partial GET method is intended to
reduce unnecessary network usage by
allowing partially-retrieved entities
to be completed without transferring
data already held by the client.
The response to a GET request is
cacheable if and only if it meets the
requirements for HTTP caching
described in section 13.
See section 15.1.3 for security
considerations when used for forms.
9.5 POST
The POST method is used to request
that the origin server accept the
entity enclosed in the request as a
new subordinate of the resource
identified by the Request-URI in the
Request-Line. POST is designed to
allow a uniform method to cover the
following functions:
- Annotation of existing resources;
- Posting a message to a bulletin board, newsgroup, mailing
list,
or similar group of articles;
- Providing a block of data, such as the result of submitting a
form, to a data-handling process;
- Extending a database through an append operation. The actual
function performed by the POST method
is determined by the server and is
usually dependent on the Request-URI.
The posted entity is subordinate to
that URI in the same way that a file
is subordinate to a directory
containing it, a news article is
subordinate to a newsgroup to which it
is posted, or a record is subordinate
to a database.
The action performed by the POST
method might not result in a resource
that can be identified by a URI. In
this case, either 200 (OK) or 204 (No
Content) is the appropriate response
status, depending on whether or not
the response includes an entity that
describes the result.
If a resource has been created on the
origin server, the response SHOULD be
201 (Created) and contain an entity
which describes the status of the
request and refers to the new
resource, and a Location header (see
section 14.30).
Responses to this method are not
cacheable, unless the response
includes appropriate Cache-Control or
Expires header fields. However, the
303 (See Other) response can be used
to direct the user agent to retrieve a
cacheable resource.
POST requests MUST obey the message
transmission requirements set out in
section 8.2.
See section 15.1.3 for security
considerations.
As stated, the response may change with GET if the request message has conditionals based on certain criteria. The POST requires that the server accept the request, no matter what.
Anytime you do a web search and you want to link someone to it, you can easily do it through:
http://www.google.com/search?q=lol
Can you imagine telling someone to do a POST request instead? A POST request isn't really bookmarkable like that, which is why GET is useful.
They simply have different purposes, as stated in other answers. GET is for GETing, POST is for POSTing.
Everything can also be achieved using raw TCP connections. Yet we often use HTTP rather than raw TCP connections because HTTP offers a layer of abstraction and, therefore, convenience and conforming implementations. Likewise, we use HTTP correctly (GETs, POSTs, PUTs, DELETEs, etc) rather than dumbly (POSTs only) because these verbs offer an additional layer of abstraction and, therefore, convenience and conforming implementations.
Lets say I want to send a variable to a page via a link, can I do that with POST? Nope, but with GET, I can send something over by doing ?variableName=someValue
You're right, everything can be tunnel through an HTTP POST. In fact, SOAP web services do exactly that. Everything is a POST using SOAP web services.
In that case, you are tunneling through HTTP, and not using HTTP to its fullest. If that's all you want to do, then that's fine.
However, if you wish to leverage HTTP for the features and benefits that it provides beyond simple message transport, then you should read the RFC and learn the rest of the HTTP protocol including GET, PUT, POST, DELETE, and all of the headers, cache management and result codes.

HTTP Status 412 (Precondition Failed) and Database Versioning

I am implementing a RESTful web service that accesses a database. Entities in the database are versioned to detect multiple updates. For instance, if the current value is {"name":"Bill", "comment":"tinker", "version":3}, if one user PUTs {"name":"Bill", "comment":"tailor", "version":3}, the request will succeed (200 OK) and the new value will be {"name":"Bill", "comment":"tailor", "version":4}. If a second user PUTs {"name":"Bill", "comment":"sailor", "version":3"} that request will fail (409 Conflict) because the version number does not match.
There are existing non-RESTful interfaces, so the design of the databases cannot be changed. The RESTful interface calls an existing interface that handles the details of checking the version.
A rule of thumb in RESTful web services is to follow the details of HTTP whenever possible. Would it be better in this case to use a conditional header in the request and return 412 Precondition Failed if the version does not match? The appropriate header appears to be If-Match. This header takes an ETag (Entity Tag) which could be a hash of the representation of the current state of the resource.
If I did this, the ETags would be for appearances' sake, because the version would still be the real thing I'm testing for.
Is there any reason I should do this, other than "making it more RESTful", whatever that is supposed to mean?
The appropriate thing to do is always to follow the HTTP spec if you're using HTTP, and the reason is simply to allow people who understand the spec to function correctly.
412 should only be used if a precondition (e.g. If-Match) caused the version matching to fail, whereas 409 should be used if the entity would cause a conflict (the HTTP spec itself alludes to this behaviour in the definition of 409).
Therefore, a client that doesn't send ETags won't be expecting a 412. Conversely, a client that does send ETags won't understand that it's ETags that are causing a 409.
I would stick with one way. You say that "the database schema can't change", but that doesn't stop you (right in the HTTP server layer) to extract the version from the datbase representation and put it in the ETag, and then on the way in, take the If-Match header and put it back in the version field.
But doing it completely in the entity body itself isn't forbidden. It just requires you to explain the concept and how it works, whereas with the ETag solution you can just point people to the HTTP spec.
Edit: And the version flag doesn't have to be a hash of the current resource; a version is quite acceptable. ETag: "3" is a perfectly valid ETag.

What's the difference between a POST and a PUT HTTP REQUEST?

They both seem to be sending data to the server inside the body, so what makes them different?
HTTP PUT:
PUT puts a file or resource at a specific URI, and exactly at that URI. If there's already a file or resource at that URI, PUT replaces that file or resource. If there is no file or resource there, PUT creates one. PUT is idempotent, but paradoxically PUT responses are not cacheable.
HTTP 1.1 RFC location for PUT
HTTP POST:
POST sends data to a specific URI and expects the resource at that URI to handle the request. The web server at this point can determine what to do with the data in the context of the specified resource. The POST method is not idempotent, however POST responses are cacheable so long as the server sets the appropriate Cache-Control and Expires headers.
The official HTTP RFC specifies POST to be:
Annotation of existing resources;
Posting a message to a bulletin board, newsgroup, mailing list,
or similar group of articles;
Providing a block of data, such as the result of submitting a
form, to a data-handling process;
Extending a database through an append operation.
HTTP 1.1 RFC location for POST
Difference between POST and PUT:
The RFC itself explains the core difference:
The fundamental difference between the
POST and PUT requests is reflected in
the different meaning of the
Request-URI. The URI in a POST request
identifies the resource that will
handle the enclosed entity. That
resource might be a data-accepting
process, a gateway to some other
protocol, or a separate entity that
accepts annotations. In contrast, the
URI in a PUT request identifies the
entity enclosed with the request --
the user agent knows what URI is
intended and the server MUST NOT
attempt to apply the request to some
other resource. If the server desires
that the request be applied to a
different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make
its own decision regarding whether or not to redirect the request.
Additionally, and a bit more concisely, RFC 7231 Section 4.3.4 PUT states (emphasis added),
4.3.4. PUT
The PUT method requests that the state of the target resource be
created or replaced with the state defined by the representation
enclosed in the request message payload.
Using the right method, unrelated aside:
One benefit of REST ROA vs SOAP is that when using HTTP REST ROA, it encourages the proper usage of the HTTP verbs/methods. So for example you would only use PUT when you want to create a resource at that exact location. And you would never use GET to create or modify a resource.
Only semantics.
An HTTP PUT is supposed to accept the body of the request, and then store that at the resource identified by the URI.
An HTTP POST is more general. It is supposed to initiate an action on the server. That action could be to store the request body at the resource identified by the URI, or it could be a different URI, or it could be a different action.
PUT is like a file upload. A put to a URI affects exactly that URI. A POST to a URI could have any effect at all.
To give examples of REST-style resources:
POST /books with a bunch of book information might create a new book, and respond with the new URL identifying that book: /books/5.
PUT /books/5 would have to either create a new book with the ID of 5, or replace the existing book with ID 5.
In non-resource style, POST can be used for just about anything that has a side effect. One other difference is that PUT should be idempotent: multiple PUTs of the same data to the same URL should be fine, whereas multiple POSTs might create multiple objects or whatever it is your POST action does.
GET: Retrieves data from the server. Should have no other effect.
PUT: Replaces target resource with the request payload. Can be used to update or create a new resource.
PATCH: Similar to PUT, but used to update only certain fields within an existing resource.
POST: Performs resource-specific processing on the payload. Can be used for different actions including creating a new resource, uploading a file, or submitting a web form.
DELETE: Removes data from the server.
TRACE: Provides a way to test what the server receives. It simply returns what was sent.
OPTIONS: Allows a client to get information about the request methods supported by a service. The relevant response header is Allow with supported methods. Also used in CORS as preflight request to inform the server about actual the request method and ask about custom headers.
HEAD: Returns only the response headers.
CONNECT: Used by the browser when it knows it talks to a proxy and the final URI begins with https://. The intent of CONNECT is to allow end-to-end encrypted TLS sessions, so the data is unreadable to a proxy.
PUT is meant as a a method for "uploading" stuff to a particular URI, or overwriting what is already in that URI.
POST, on the other hand, is a way of submitting data RELATED to a given URI.
Refer to the HTTP RFC
As far as i know, PUT is mostly used for update the records.
POST - To create document or any other resource
PUT - To update the created document or any other resource.
But to be clear on that PUT usually 'Replaces' the existing record if it is there and creates if it not there..
Define operations in terms of HTTP methods
The HTTP protocol defines a number of methods that assign semantic meaning to a request. The common HTTP methods used by most RESTful web APIs are:
GET retrieves a representation of the resource at the specified URI. The body of the response message contains the details of the requested resource.
POST creates a new resource at the specified URI. The body of the request message provides the details of the new resource. Note that POST can also be used to trigger operations that don't actually create resources.
PUT either creates or replaces the resource at the specified URI. The body of the request message specifies the resource to be created or updated.
PATCH performs a partial update of a resource. The request body specifies the set of changes to apply to the resource.
DELETE removes the resource at the specified URI.
The effect of a specific request should depend on whether the resource is a collection or an individual item. The following table summarizes the common conventions adopted by most RESTful implementations using the e-commerce example. Not all of these requests might be implemented—it depends on the specific scenario.
Resource
POST
GET
PUT
DELETE
/customers
Create a new customer
Retrieve all customers
Bulk update of customers
Remove all customers
/customers/1
Error
Retrieve the details for customer 1
Update the details of customer 1 if it exists
Remove customer 1
/customers/1/orders
Create a new order for customer 1
Retrieve all orders for customer 1
Bulk update of orders for customer 1
Remove all orders for customer 1
The differences between POST, PUT, and PATCH can be confusing.
A POST request creates a resource. The server assigns a URI for the new resource and returns that URI to the client. In the REST model, you frequently apply POST requests to collections. The new resource is added to the collection. A POST request can also be used to submit data for processing to an existing resource, without any new resource being created.
A PUT request creates a resource or updates an existing resource. The client specifies the URI for the resource. The request body contains a complete representation of the resource. If a resource with this URI already exists, it is replaced. Otherwise, a new resource is created, if the server supports doing so. PUT requests are most frequently applied to resources that are individual items, such as a specific customer, rather than collections. A server might support updates but not creation via PUT. Whether to support creation via PUT depends on whether the client can meaningfully assign a URI to a resource before it exists. If not, then use POST to create resources and PUT or PATCH to update.
A PATCH request performs a partial update to an existing resource. The client specifies the URI for the resource. The request body specifies a set of changes to apply to the resource. This can be more efficient than using PUT, because the client only sends the changes, not the entire representation of the resource. Technically PATCH can also create a new resource (by specifying a set of updates to a "null" resource), if the server supports this.
PUT requests must be idempotent. If a client submits the same PUT request multiple times, the results should always be the same (the same resource will be modified with the same values). POST and PATCH requests are not guaranteed to be idempotent.
Others have already posted excellent answers, I just wanted to add that with most languages, frameworks, and use cases you'll be dealing with POST much, much more often than PUT. To the point where PUT, DELETE, etc. are basically trivia questions.
Please see: http://zacharyvoase.com/2009/07/03/http-post-put-diff/
I’ve been getting pretty annoyed lately by a popular misconception by web developers that a POST is used to create a resource, and a PUT is used to update/change one.
If you take a look at page 55 of RFC 2616 (“Hypertext Transfer Protocol – HTTP/1.1”), Section 9.6 (“PUT”), you’ll see what PUT is actually for:
The PUT method requests that the enclosed entity be stored under the supplied Request-URI.
There’s also a handy paragraph to explain the difference between POST and PUT:
The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request – the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource.
It doesn’t mention anything about the difference between updating/creating, because that’s not what it’s about. It’s about the difference between this:
obj.set_attribute(value) # A POST request.
And this:
obj.attribute = value # A PUT request.
So please, stop the spread of this popular misconception. Read your RFCs.
A POST is considered something of a factory type method. You include data with it to create what you want and whatever is on the other end knows what to do with it. A PUT is used to update existing data at a given URL, or to create something new when you know what the URI is going to be and it doesn't already exist (as opposed to a POST which will create something and return a URL to it if necessary).
It should be pretty straightforward when to use one or the other, but complex wordings are a source of confusion for many of us.
When to use them:
Use PUT when you want to modify a singular resource that is already a part of resource collection. PUT replaces the resource in its entirety. Example: PUT /resources/:resourceId
Sidenote: Use PATCH if you want to update a part of the resource.
Use POST when you want to add a child resource under a collection of resources.
Example: POST => /resources
In general:
Generally, in practice, always use PUT for UPDATE operations.
Always use POST for CREATE operations.
Example:
GET /company/reports => Get all reports
GET /company/reports/{id} => Get the report information identified by "id"
POST /company/reports => Create a new report
PUT /company/reports/{id} => Update the report information identified by "id"
PATCH /company/reports/{id} => Update a part of the report information identified by "id"
DELETE /company/reports/{id} => Delete report by "id"
The difference between POST and PUT is that PUT is idempotent, that means, calling the same PUT request multiple times will always produce the same result(that is no side effect), while on the other hand, calling a POST request repeatedly may have (additional) side effects of creating the same resource multiple times.
GET : Requests using GET only retrieve data , that is it requests a representation of the specified resource
POST : It sends data to the server to create a resource. The type of the body of the request is indicated by the Content-Type header. It often causes a change in state or side effects on the server
PUT : Creates a new resource or replaces a representation of the target resource with the request payload
PATCH : It is used to apply partial modifications to a resource
DELETE : It deletes the specified resource
TRACE : It performs a message loop-back test along the path to the target resource, providing a useful debugging mechanism
OPTIONS : It is used to describe the communication options for the target resource, the client can specify a URL for the OPTIONS method, or an asterisk (*) to refer to the entire server.
HEAD : It asks for a response identical to that of a GET request, but without the response body
CONNECT : It establishes a tunnel to the server identified by the target resource , can be used to access websites that use SSL (HTTPS)
In simple words you can say:
1.HTTP Get:It is used to get one or more items
2.HTTP Post:It is used to create an item
3.HTTP Put:It is used to update an item
4.HTTP Patch:It is used to partially update an item
5.HTTP Delete:It is used to delete an item
It would be worth mentioning that POST is subject to some common Cross-Site Request Forgery (CSRF) attacks while PUT isn't.
The CSRF below are not possible with PUT when the victim visits attackersite.com.
The effect of the attack is that the victim unintentionally deletes a user just because it (the victim) was logged-in as admin on target.site.com, before visiting attackersite.com:
Malicious code on attackersite.com:
Case 1: Normal request. saved target.site.com cookies will automatically be sent by the browser: (note: supporting PUT only, at the endpoint, is safer because it is not a supported <form> attribute value)
<!--deletes user with id 5-->
<form id="myform" method="post" action="http://target.site.com/deleteUser" >
<input type="hidden" name="userId" value="5">
</form>
<script>document.createElement('form').submit.call(document.getElementById('myform'));</script>
Case 2: XHR request. saved target.site.com cookies will automatically be sent by the browser: (note: supporting PUT only, at the endpoint, is safer because an attempt to send PUT would trigger a preflight request, whose response would prevent the browser from requesting the deleteUser page)
//deletes user with id 5
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://target.site.com/deleteUser");
xhr.withCredentials=true;
xhr.send(["userId=5"]);
MDN Ref : [..]Unlike “simple requests” (discussed above), --[[ Means: POST/GET/HEAD ]]--, for "preflighted" requests the browser first sends an HTTP request using the OPTIONS method[..]
cors in action : [..]Certain types of requests, such as DELETE or PUT, need to go a step further and ask for the server’s permission before making the actual request[..]what is called a preflight request[..]
REST-ful usage
POST is used to create a new resource and then returns the resource URI
EX
REQUEST : POST ..../books
{
"book":"booName",
"author":"authorName"
}
This call may create a new book and returns that book URI
Response ...THE-NEW-RESOURCE-URI/books/5
PUT is used to replace a resource, if that resource is exist then simply update it, but if that resource doesn't exist then create it,
REQUEST : PUT ..../books/5
{
"book":"booName",
"author":"authorName"
}
With PUT we know the resource identifier, but POST will return the new resource identifier
Non REST-ful usage
POST is used to initiate an action on the server side, this action may or may not create a resource, but this action will have side affects always it will change something on the server
PUT is used to place or replace literal content at a specific URL
Another difference in both REST-ful and non REST-ful styles
POST is Non-Idempotent Operation: It will cause some changes if executed multiple times with the same request.
PUT is Idempotent Operation: It will have no side-effects if executed multiple times with the same request.
Actually there's no difference other than their title. There's actually a basic difference between GET and the others. With a "GET"-Request method, you send the data in the url-address-line, which are separated first by a question-mark, and then with a & sign.
But with a "POST"-request method, you can't pass data through the url, but you have to pass the data as an object in the so called "body" of the request. On the server side, you have then to read out the body of the received content in order to get the sent data.
But there's on the other side no possibility to send content in the body, when you send a "GET"-Request.
The claim, that "GET" is only for getting data and "POST" is for posting data, is absolutely wrong. Noone can prevent you from creating new content, deleting existing content, editing existing content or do whatever in the backend, based on the data, that is sent by the "GET" request or by the "POST" request. And nobody can prevent you to code the backend in a way, that with a "POST"-Request, the client asks for some data.
With a request, no matter which method you use, you call a URL and send or don't send some data to specify, which information you want to pass to the server to deal with your request, and then the client gets an answer from the server. The data can contain whatever you want to send, the backend is allowed to do whatever it wants with the data and the response can contain any information, that you want to put in there.
There are only these two BASIC METHODS. GET and POST. But it's their structure, which makes them different and not what you code in the backend. In the backend you can code whatever you want to, with the received data. But with the "POST"-request you have to send/retrieve the data in the body and not in the url-addressline, and with a "GET" request, you have to send/retrieve data in the url-addressline and not in the body. That's all.
All the other methods, like "PUT", "DELETE" and so on, they have the same structure as "POST".
The POST Method is mainly used, if you want to hide the content somewhat, because whatever you write in the url-addressline, this will be saved in the cache and a GET-Method is the same as writing a url-addressline with data. So if you want to send sensitive data, which is not always necessarily username and password, but for example some ids or hashes, which you don't want to be shown in the url-address-line, then you should use the POST method.
Also the URL-Addressline's length is limited to 1024 symbols, whereas the "POST"-Method is not restricted. So if you have a bigger amount of data, you might not be able to send it with a GET-Request, but you'll need to use the POST-Request. So this is also another plus point for the POST-request.
But dealing with the GET-request is way easier, when you don't have complicated text to send.
Otherwise, and this is another plus point for the POST method, is, that with the GET-method you need to url-encode the text, in order to be able to send some symbols within the text or even spaces. But with a POST method you have no restrictions and your content doesn't need to be changed or manipulated in any way.
Summary
Use PUT to create or replace the state of the target resource with the state defined by the representation enclosed in the request. That standardized intended effect is idempotent so it informs intermediaries that they can repeat a request in case of communication failure.
Use POST otherwise (including to create or replace the state of a resource other than the target resource). Its intended effect is not standardized so intermediaries cannot rely on any universal property.
References
The latest authoritative description of the semantic difference between the POST and PUT request methods is given in RFC 7231 (Roy Fielding, Julian Reschke, 2014):
The fundamental difference between the POST and PUT methods is highlighted by the different intent for the enclosed representation. The target resource in a POST request is intended to handle the enclosed representation according to the resource's own semantics, whereas the enclosed representation in a PUT request is defined as replacing the state of the target resource. Hence, the intent of PUT is idempotent and visible to intermediaries, even though the exact effect is only known by the origin server.
In other words, the intended effect of PUT is standardized (create or replace the state of the target resource with the state defined by the representation enclosed in the request) and so is common to all target resources, while the intended effect of POST is not standardized and so is specific to each target resource. Thus POST can be used for anything, including for achieving the intended effects of PUT and other request methods (GET, HEAD, DELETE, CONNECT, OPTIONS, and TRACE).
But it is recommended to always use the more specialized request method rather than POST when applicable because it provides more information to intermediaries for automating information retrieval (since GET, HEAD, OPTIONS, and TRACE are defined as safe), handling communication failure (since GET, HEAD, PUT, DELETE, OPTIONS, and TRACE are defined as idempotent), and optimizing cache performance (since GET and HEAD are defined as cacheable), as explained in It Is Okay to Use POST (Roy Fielding, 2009):
POST only becomes an issue when it is used in a situation for which some other method is ideally suited: e.g., retrieval of information that should be a representation of some resource (GET), complete replacement of a representation (PUT), or any of the other standardized methods that tell intermediaries something more valuable than “this may change something.” The other methods are more valuable to intermediaries because they say something about how failures can be automatically handled and how intermediate caches can optimize their behavior. POST does not have those characteristics, but that doesn’t mean we can live without it. POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”
Both PUT and POST are Rest Methods .
PUT - If we make the same request twice using PUT using same parameters both times, the second request will not have any effect. This is why PUT is generally used for the Update scenario,calling Update more than once with the same parameters doesn't do anything more than the initial call hence PUT is idempotent.
POST is not idempotent , for instance Create will create two separate entries into the target hence it is not idempotent so CREATE is used widely in POST.
Making the same call using POST with same parameters each time will cause two different things to happen, hence why POST is commonly used for the Create scenario
Post and Put are mainly used for post the data and other update the data. But you can do the same with post request only.

Resources