Tuesday, May 17. 2005
PUT vs. POST
I had some PUT vs. POST confusion the other day when talking about rest. According to the HTTP/1.1 Spec: " 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" i.e. Create. " The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI." That is, a Create or an Update.
But the differences are more subtle then that.
When you POST something to a resource, you are POSTing it to a resource handler. When you are PUTting a resource, you are PUTting to the actual resource itself.
So, you would POST to /user/new to create a new user. Or, you could PUT to /user/fiver to create or update an existing user named 'fiver'.
(I've updated the original entry to reflect that.)
Update: Avi Flax in the comments is totally correct. This post was made when I was a REST greenhorn, and didn't quite understand the URI as noun, method as verb concept.
But the differences are more subtle then that.
When you POST something to a resource, you are POSTing it to a resource handler. When you are PUTting a resource, you are PUTting to the actual resource itself.
So, you would POST to /user
(I've updated the original entry to reflect that.)
Update: Avi Flax in the comments is totally correct. This post was made when I was a REST greenhorn, and didn't quite understand the URI as noun, method as verb concept.
Comments
Display comments as
(Linear | Threaded)
So, you would POST to /user/new to create a new user.
Interesting. The way I've been thinking about POST, I would POST to "/user" to create a new user. "/user/new" is a non-resource, it doesn't exist. That isn't to say that a REST app shouldn't expose pseudo-resources, I'm not sure about that -- but I think POST is intended to be sent to the container/parent resource directly.
Interesting. The way I've been thinking about POST, I would POST to "/user" to create a new user. "/user/new" is a non-resource, it doesn't exist. That isn't to say that a REST app shouldn't expose pseudo-resources, I'm not sure about that -- but I think POST is intended to be sent to the container/parent resource directly.
You are of course correct. A POST to /user to create a user, versus a post to /user/new.
Looks like I need to update this entry.
Looks like I need to update this entry.
Cool, 1 gold star for me!
Another note: in the REST app I'm working on, I use a plural name to denote a collection. Examples:
http://system.com/users/avi
http://system.com/log/events/345566
Another note: in the REST app I'm working on, I use a plural name to denote a collection. Examples:
http://system.com/users/avi
http://system.com/log/events/345566
Thanks for catching that BTW... ;)
plural names as a collection totally makes sense. I'm still working out the implications of decoupling the resources from the filesystem. On one hand when the URI is not related to the filesystem at all, you get a tremendous amount of flexibility.
On the other hand, I think that the filesystem is a really good mapping between a URI and the "physical" resource on the server. I.e. if I am referring to the users resource on system.com, then it is the resourse emitted by /DOCUMENT_ROOT/users.(php|cfm|jsp)
It makes understanding a website and is associated resources much easier (in my eyes)
But like I said, I am still working through all the implications.
plural names as a collection totally makes sense. I'm still working out the implications of decoupling the resources from the filesystem. On one hand when the URI is not related to the filesystem at all, you get a tremendous amount of flexibility.
On the other hand, I think that the filesystem is a really good mapping between a URI and the "physical" resource on the server. I.e. if I am referring to the users resource on system.com, then it is the resourse emitted by /DOCUMENT_ROOT/users.(php|cfm|jsp)
It makes understanding a website and is associated resources much easier (in my eyes)
But like I said, I am still working through all the implications.
Jonnay, I totally agree that a direct filesystem->URL structure mapping is simple, convenient, and effective -- for websites.
However, the definition of "website" is evolving, or fragmenting, or something -- I don't know! As I see it, the WWW was originally a document publishing system. Then it sprouted a new type of software platform -- which was shoehorned onto a publishing system. So then a website was either a collection of documents or a software application structured like a collection of documents - or both at the same time.
So it's only natural that we have a lot of uncertainty and befuddlement about what the hell is going on.
I see the development of REST applications as a clear way to use the WWW as a software platform, distinct from a website comprised of documents.
With these new REST applications, which really aren't "websites" as we know them -- although they can contain and serve documents, the application is more than a collection of documents -- I've found that the best thing we can do to fully realize their potential is to decouple them from our internal conceptual model of a "website" and think of them as a new kind of entity.
So, now we have this new entity: a REST application. It can be thought of as a tree/collection of resources contained in a single root resource, each of which can contain child resources of their own. As you know, a URL structure can be mapped the same way, as can a filesystem. So what's the problem?
Methods!
In a REST application, as you know, most resources will support 2-4 of the "major" HTTP methods. For instance, "/users" will probably support GET and POST. "/users/avi" will probably support GET, PUT, and DELETE, and maybe POST too.
OK, so what? Couldn't we have a single file for each resource, which would be coded to detect which method was specified, and take the proper action and return the proper response?
Sure we could. But I see two problems with that approach:
(1) This is a little too similar to a conventional website. That's fine for a conventional website, but when constructing a REST application, it's important that we disassociate it from our conceptual model of what a website is. When we see users.php and user.php, it will line up with our conceptual model of a website, where most resources are intented to support only GET, with a few supporting POST. This may seem silly, but I think it's the only way for us to realize the full potential of this new application architecture without being hampered by past conventions.
(2)There's a strong possibility of a lot of code duplication happening, without much reuse. I suppose this could be avoided by encapsulating the behavior in classes, but there are still a lot of files to deal with, and a lot of code scattered around. It just feels a bit messy to me.
... so, in my current project, I've abstracted resources into application concepts that a central request handler processes and returns the appropriate response/representation.
I suppose there could be a middle ground, though: some fancy HTACCESS mod_rewrite magic could enable a structure like this:
/wwwroot/resources/users/get.php
/wwwroot/resources/users/post.php
/wwwroot/resources/users/user/get.php
/wwwroot/resources/users/user/put.php
/wwwroot/resources/users/user/delete.php
and so on. Again there are a lot of files and shared libraries would be necessary to reduce code duplication, but it would probably work fairly well. However, I personally wouldn't want to have the job of writing all those mod_rewrite rules.
Whew, I think that's quite enough for now! I am *done*!
Please forgive me if this seems like lecturing or something, really I'm just thinking out l... ah, through my fingers. Thanks for letting me blather on!
(BTW why not allow some HTML in the comments?)
However, the definition of "website" is evolving, or fragmenting, or something -- I don't know! As I see it, the WWW was originally a document publishing system. Then it sprouted a new type of software platform -- which was shoehorned onto a publishing system. So then a website was either a collection of documents or a software application structured like a collection of documents - or both at the same time.
So it's only natural that we have a lot of uncertainty and befuddlement about what the hell is going on.
I see the development of REST applications as a clear way to use the WWW as a software platform, distinct from a website comprised of documents.
With these new REST applications, which really aren't "websites" as we know them -- although they can contain and serve documents, the application is more than a collection of documents -- I've found that the best thing we can do to fully realize their potential is to decouple them from our internal conceptual model of a "website" and think of them as a new kind of entity.
So, now we have this new entity: a REST application. It can be thought of as a tree/collection of resources contained in a single root resource, each of which can contain child resources of their own. As you know, a URL structure can be mapped the same way, as can a filesystem. So what's the problem?
Methods!
In a REST application, as you know, most resources will support 2-4 of the "major" HTTP methods. For instance, "/users" will probably support GET and POST. "/users/avi" will probably support GET, PUT, and DELETE, and maybe POST too.
OK, so what? Couldn't we have a single file for each resource, which would be coded to detect which method was specified, and take the proper action and return the proper response?
Sure we could. But I see two problems with that approach:
(1) This is a little too similar to a conventional website. That's fine for a conventional website, but when constructing a REST application, it's important that we disassociate it from our conceptual model of what a website is. When we see users.php and user.php, it will line up with our conceptual model of a website, where most resources are intented to support only GET, with a few supporting POST. This may seem silly, but I think it's the only way for us to realize the full potential of this new application architecture without being hampered by past conventions.
(2)There's a strong possibility of a lot of code duplication happening, without much reuse. I suppose this could be avoided by encapsulating the behavior in classes, but there are still a lot of files to deal with, and a lot of code scattered around. It just feels a bit messy to me.
... so, in my current project, I've abstracted resources into application concepts that a central request handler processes and returns the appropriate response/representation.
I suppose there could be a middle ground, though: some fancy HTACCESS mod_rewrite magic could enable a structure like this:
/wwwroot/resources/users/get.php
/wwwroot/resources/users/post.php
/wwwroot/resources/users/user/get.php
/wwwroot/resources/users/user/put.php
/wwwroot/resources/users/user/delete.php
and so on. Again there are a lot of files and shared libraries would be necessary to reduce code duplication, but it would probably work fairly well. However, I personally wouldn't want to have the job of writing all those mod_rewrite rules.
Whew, I think that's quite enough for now! I am *done*!
Please forgive me if this seems like lecturing or something, really I'm just thinking out l... ah, through my fingers. Thanks for letting me blather on!
(BTW why not allow some HTML in the comments?)
Add Comment





Two great tastes...And by Ajax, I am not referring to a minty coloured and burning flavoured scouring powder, but instead some geek-shit. AJAX is deceptively simple. It stands for Asynchronous Javascript and XML. The basic theory is that you can use
Tracked: May 17, 15:30
That is to say, REST does not equal CRUD, dammit! Sadly, even I made the flawed analogy of Rest and CRUD. It is an excusable one, because it is so easy to map POST to create, and PUT to update, but this misses the deeper semantics of the HTTP verbs, a
Tracked: Mar 07, 09:12
In my research on REST this last week, I’ve seen several comments noting confusion on whether to use PUT or POST. After reading several references (Elliotte Rusty Harold, Sacrificial Rabbit, and Mark Baker) , I loosely paraphrase the rule as: Us...
Tracked: Nov 04, 10:26