42

Shouldn't PUT be used to Create and POST used to Update since PUT is idempotent.

That way multiple PUTs for the same Order will place only one Order?

Henke
  • 4,445
  • 3
  • 31
  • 44
Tawani
  • 11,067
  • 20
  • 82
  • 106

5 Answers5

74

The difference is that a PUT is for a known resource, and therefor used for updating, as stated here in rfc2616.

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.

I do see where you are coming from based on the names themselves however.

I usually look at POST as it should be the URI that will handle the content of my request (in most cases the params as form values) and thus creating a new resource, and PUT as the URI which is the subject of my request (/users/1234), a resource which already exists.

I believe the nomenclature goes back a long ways, consider the early web. One might want to POST their message to a message board, and then PUT additional content into their message at a later date.

JP Silvashy
  • 46,977
  • 48
  • 149
  • 227
  • 17
    To extend this a bit, I think it might be clearer to think of PUT as a synonym for "set" and POST as a synonym for "create child of". I wouldn't think of either as "create" or "update" because it will give you the wrong intuition. – John Watts Jun 04 '12 at 17:43
  • Good point @JohnWatts, this is the typical use case, rarely should you have to do something out of the norm here. If you are handling requests in a non-standard way, you may want to rethink the intention of what you're trying to do in the first place. – JP Silvashy Jun 04 '12 at 18:22
  • 8
    Martin Fowler says "[some people incorrectly make a correspondence between `POST`/`PUT` and `create`/`update`](http://martinfowler.com/articles/richardsonMaturityModel.html)" – Marius Butuc Nov 18 '12 at 02:13
  • 1
    @JPSilvashy That's not quite true, you can use PUT to create resources as well. If it is your client generating for example the GUID that identifies the resource then, it's perfectly valid to use PUT. Fallowing this approach, POST is meaningless, as all the updates should be done issuing a PATCH. – MeTitus Jan 28 '16 at 09:46
  • @Marco you _could_ user your service to create a resource from a GET request as well. You are free to misuse the spec anyway you please, but there is a "best-practices" approach as well. – JP Silvashy Apr 08 '16 at 17:47
  • @JPSilvashy well you surely can, but you will work against all the conventions. – MeTitus Apr 09 '16 at 21:04
  • 1
    The specs state PUT can be used to create resources. Does not say this with POST, rather its just used to send data to a server.~ The link you posted even states PUT is for resource creation... `The PUT method requests that the enclosed entity be stored under the supplied Request-URI` – Emobe Nov 26 '19 at 12:53
18

There's no strict correspondence between HTTP methods and CRUD. This is a convention adopted by some frameworks, but it has nothing to do with REST constraints.

A PUT request asks the server to replace whatever is at the given URI with the enclosed representation, completely ignoring the current contents. A good analogy is the mv command in a shell. It creates the new file at the destination if it doesn't exist, or replaces whatever exists. In either case, it completely ignores whatever is in there. You can use this to create, but also to update something, as long as you're sending a complete representation.

POST asks the target resource to process the payload according to predefined rules, so it's the method to use for any operation that isn't already standardized by the HTTP protocol. This means a POST can do anything you want, as long as you're not duplicating functionality from other method -- for instance, using POST for retrieval when you should be using GET -- and you document it properly.

So, you can use both for create and update, depending on the exact circumstances, but with PUT you must have consistent semantics for everything in your API and you can't make partial updates, and with POST you can do anything you want, as long as you document how exactly it works.

Pedro Werneck
  • 40,902
  • 7
  • 64
  • 85
  • I think this is the most simplistic and agnostic response. It doesn't matter the framework, REST, methodology, it's up to the process you want to encourage the verb you should impose. PUT will do one thing, POST whatever you want to do! Cristal clear! – Pablo Ezequiel Leone Dec 14 '17 at 11:35
  • This answer also jibes with the quote from RFC2616 in https://stackoverflow.com/a/10885212/1168342 – Fuhrmanator May 09 '18 at 19:55
  • 1
    But "*with `POST` you can do anything you want*" implies that your `POST` could be idempotent. Seems like that's wrong, right? `POST` [conventionally] creates a new entity every time. `PUT` potentially updates the entity for that specific URI, and the call with the same parameters would leave you in the same state every time. **Or are you arguing against non-idempotent `POST`s?** – ruffin Jan 28 '19 at 21:40
  • 1
    @ruffin You can do anything with POST. The semantics of POST are defined by the target resource. If it defines idempotent or non-idempotent behavior, that's fine. – Pedro Werneck Jan 29 '19 at 15:58
  • @ruffin PUT would be idempotent, since it sends a complete representation. – IAM_AL_X Apr 15 '20 at 22:15
  • @IAM_AL_X Yep, that's why I said, "the [PUT] call with the same parameters would leave you in the same state every time". But what Pedro has here (comment & answer) is that POST is a wild west; anything can happen. I'd agree that in practice that's how it shakes out, but I would likely argue that **imo POST should _not_**, by convention, **act idempotently** (if that's a word) in a codebase where I have a level of cultural control. Corollary: If you want to update part of an entity, PATCH it, don't PUT OR POST. /shrug, 2¢, YMMV, etc. Confession: I also argue GET can have a body for searching. – ruffin Apr 16 '20 at 15:20
7

PUT should be used for creates if and only if possible URI of the new resource is known for a client. New URI maybe advertised by the service in resource representation. For example service may provide with some kind of submit form and specify action URI on it which can be a pre populated URI of the new resource. In this case yes, if initial PUT request successfully creates resource following PUT request will only replace it.

It's ok to use POST for updates, it was never said that POST is for "create" operations only.

ioseb
  • 16,625
  • 3
  • 33
  • 29
3

You are trying to correlate CRUD to HTTP, and that doesn't work. The philosophy of HTTP is different, and does not natively correspond to CRUD. The confusion arises because of REST; which does correspond to CRUD. REST uses HTTP, but with additional constraints upon what is allowed. I've prepared this Q & A to explain the HTTP approach to things:

What's being requested?

  • A POST requests an action upon a collection.
  • A PUT requests the placement of a resource into a collection.

What kind of object is named in the URI?

  • The URI of a POST identifies a collection.
  • The URI of a PUT identifies a resource (within a collection).

How is the object specified in the URI, for POST and PUT respectively?

/collectionId
/collectionId/resourceId

How much freedom does the HTTP protocol grant the collection?

  • With a POST, the collection is in control.
  • With a PUT, the requestor is in control (unless request fails).

What guarantees does the HTTP protocol make?

  • With a POST, the HTTP protocol does not define what is supposed to happen with the collection; the rfc states that the server should "process ... the request according to the [collection's] own specific semantics." (FYI: The rfc uses the confusing phrase "target resource" to mean "collection".) It is up to the server to decide upon a contract that defines what a POST will do.
  • With a PUT, the HTTP protocol requires that a response of "success" must guarantee that the collection now contains a resource with the ID and content specified by the request.

Can the operation result in the creation of a new resource within the collection?

  • Yes, or no, depending upon the contract. If the contract is a REST protocol, then insertion is required. When a POST creates a new resource, the response will be 201.
  • Yes, but that means the requestor is specifying the new ID. This is fine for bulletin boards, but problematic with databases. (Hence, for database applications, PUT will generally not insert, but only update.) When a PUT creates a new resource, the response will be 201.

Is the operation idempotent?

  • A POST is generally not idempotent. (The server can offer any contract it wishes, but idempotency is generally not part of that contract).
  • A PUT is required to be idempotent. (The state of the identified resource is idempotent. Side effects outside of that resource are allowed.)

Here is the rfc: https://www.rfc-editor.org/rfc/rfc7231#section-4.3.3

Community
  • 1
  • 1
IAM_AL_X
  • 1,221
  • 11
  • 12
0

It depends.. you can create/update sites/records with both. When the client is specifying the URI then PUT is the way to go. e.g. Any Code Editor like Dreamweaver, PUT is the right protocol to use.

have also a look at this thread: put vs post in rest

Community
  • 1
  • 1
micho
  • 119
  • 1
  • 1
  • 11
  • It's not that you can create or update them with either type of request, you can _in fact_ create a resource with a GET, or DELETE if you really want to. It has a lot to do with the conventions of REST. In any case, you have to specify a URI in any request. – JP Silvashy Jun 04 '12 at 18:20