REST semantics

As part of my work at Talis, I'm currently working on a RESTful application (for library data). I've read the RESTful Web Services book, I know about RESTful Rails, I'm aware of the Atom Publishing Protocol, and I've done some work with the Amazon S3 interface. But so far I can't find a complete agreement on the exact semantics of POST vs. PUT. Which one maps onto resource creation, and which one onto update? The frameworks I mentioned above aren't in complete agreement:

  • In the RESTful Web Services book, it's complicated. POST is used to append new resources to an existing resource (creating child resources, effectively), and PUT used to create new resources where the client knows the URI of the new resource (see S3 below). "The difference between PUT and POST
    is this: the client uses PUT when it’s in charge of deciding which URI the new resource
    should have. The client uses POST when the server is in charge of deciding which URI
    the new resource should have."
  • APP specifies that a POST = create, and PUT = update.
  • In Rails, POST = create, PUT = update.
  • In S3, PUT = create (there are no updates, just overwrites).

I think it boils down to:

  • Create
    • If you are placing a new resource into a known location identified by URI, use PUT (e.g. you are creating a new web page and know where you want to serve it once it is in place on the server).
    • If you are creating a new resource and don't know where it will end up (its URI) (e.g. creating a new blog entry), use POST.
  • Update
    • If you are modifying a resource by overwriting existing data (e.g. replacing a blog entry with a new one), use PUT.
    • If you are appending new data to an existing resource (e.g. adding a comment to a blog entry), use POST.

I went back to RFC 2616 for the formal distinction between POST and PUT, which is defined as follows:

"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." (trans.: if you create a new resource "inside" an existing URI, use POST: this applies if you are doing something like creating a new resource and you don't know what its URI will be).

"The PUT method requests that the enclosed entity be stored under the supplied Request-URI." (trans.: use PUT if you know the URI of the resource you are creating or modifying).

This ties with the definition given in one of the comments by Sergio (thanks). What's interesting about this is that creating a resource where you know the resulting URI should use PUT; a modification will generally use PUT; and creating a resource where you don't know the resulting URI for it should use POST. The RESTful Web Services book follows this line.

Any other thoughts?

Comments

As In English...

I think about the verbs as what they mean in English: When you PUT something somewhere you know exactly where you are putting it. So PUT the comment on the third post (/posts/3.)

A POST is more of an application to a membership club. You POST a letter to them (/members) and they respond telling you when they've CREATEd your membership and what your member ID is (/members/42.) If you then wanted to UPDATE your member information, you would PUT that information on your profile (/members/42.)

Interesting. That seems to

Interesting. That seems to go against the grain of the definitions in the RFC/RESTful web services. If you're putting a comment on a blog post, the RFC seems to suggest you should use POST: you won't know the URI of the resulting comment resource, which is a child of the blog post. However, I think you're also correct, in that if you update your profile, you are making a change to a resource which already exists - your modifications end up on the resource you identified by URI.

I think my preference would be:

  • POST if you don't know the URI of the resource you are creating.
  • PUT if you do, or if you are directly modifying an existing resource (not appending child resources).

The difficulty, to my mind, comes from creating children of existing resources: I think this should use POST, as the client doesn't specify the created child's URI.

PUT vs. POST confusion

I would agree that the only difference between POST and PUT is whom decides the URI of the new resource. If it's POST, then the server decides. If it's PUT then the client decides.

I love Restful Rails, but I think its conventions can confuse developers. The mapping of POST to create and PUT to update in the controllers hides the fact that PUT can also be used to create resources too.

I agree, Dan. I didn't

I agree, Dan. I didn't realise the distinction until I looked at the HTTP RFC and RESTful Web Services. I'm just getting to grips with RESTful Rails, by the way, so doubtless will be putting up some blog posts about further misunderstandings and confusion :)

POST for Updates?

> Update
> - If you are modifying a resource by overwriting existing data (e.g. replacing a blog entry with a new one), use PUT.
> - If you are appending new data to an existing resource (e.g. adding a comment to a blog entry), use POST.

If you are appending new data, you are effectively creating a new resource. Therefore it is quite natural to use POST..

POST for Updates?

I think the textbook explanations are clear, but if you need another way to look at it, I like to think like this:
1 - If the data you are submitting is going to produce a new URI, then it's a creation action: POST
2 - If the data will live in an existing URI, then you're just replacing the existing content at that URI: PUT

Thanks Sergio, I think that

Thanks Sergio, I think that captures it. I think my confusion came from the fact that a create action may specify the location of the resulting new resource and therefore require PUT. (This is what happens in Amazon S3, where the URI is specified on creation of new buckets/objects, so you know exactly where they're going to be located.).