PUT vs. POST for Uploading Files - RESTful API to be Built Using Zend Framework

PostUploadPutRest

Post Problem Overview


I'm building a RESTful API using Zend Framework via the Zend_Rest_Route. For uploading of files, should I use PUT or POST to handle the process? I'm trying to be as consistent as possible with the definition of the REST verbs. Please refer to: PUT or POST: The REST of the Story.

The way I understand this is that I should use PUT if and only if I'm updating the full content of the specified resource. I'll have to know the exact URL to use PUT. On the other hand, I should use POST if I'm sending a command to the server to create a subordinate of the specified resource, using some server-side algorithm.

Let's assume this is a REST API for uploading images. Does that mean I should use POST if the server is to manipulate the image file (i.e. create thumbnail, resize, etc); and use PUT if I just want to save the raw image file to the server?

If I use PUT to handle a file upload, should the process be as follows:

  1. The user sends a GET request to retrieve the specific URL to upload the file by PUT.
  2. Then the user sends a PUT request to that URL.
    The file being uploaded is raw - exactly the one the user uploaded.

I'm quite new to this stuff; so hopefully I'm making sense here...

If you know the "best" way to do this, feel free to comment as well.

Post Solutions


Solution 1 - Post

There seems to be quite a bit of misunderstanding here. PUT versus POST is not really about replace versus create, but rather about idempotency and resource naming.

PUT is an idempotent operation. With it, you give the name of a resource and an entity to place as that resource's content (possibly with server-generated additions). Crucially, doing the operation twice in a row should result in the same thing as if it was done just once or done 20 times, for some fairly loose definition of “the same thing” (it doesn't have to be byte-for-byte identical, but the information that the user supplied should be intact). You wouldn't ever want a PUT to cause a financial transaction to be triggered.

POST is a non-idempotent operation. You don't need to give the name of the resource which you're looking to have created (nor does a POST have to create; it could de-duplicate resources if it wished). POST is often used to implement “create a resource with a newly-minted name and tell me what the name is” — the lack of idempotency implied by “newly-minted name” fits with that. Where a new resource is created, sending back the locator for the resource in a Location header is entirely the right thing to do.

Now, if you are taking the policy position that clients should never create resource names, you then get POST being the perfect fit for creation (though theoretically it could do anything based on the supplied entity) and PUT being how to do update. For many RESTful applications that makes a lot of sense, but not all; if the model being presented to the user was of a file system, having the user supply the resource name makes a huge amount of sense and PUT becomes the main creation operation (and POST becomes delegated to less common things like making an empty directory and so on; WebDAV reduces the need for POST even further).

The summary: Don't think in terms of create/update, but rather in terms of who makes the resource names and which operations are idempotent. PUT is really create-or-update, and POST is really do-anything-which-shouldnt-be-repeated-willy-nilly.

Solution 2 - Post

For file upload, unless it is replacing an existing resource, definitely use POST.

In REST, POST is to create new resources, PUT to replace existing resources, GET to retrieve resources, and DELETE to delete resources.

Source: http://en.wikipedia.org/wiki/Representational_state_transfer#RESTful_web_services

Solution 3 - Post

REST isn't a standard so this can easily turn into a religious battle. AtomPub and OData standards which are considered to be "RESTful" do agree on this though: POST = creation while PUT = updates

Solution 4 - Post

The simple answer is you should use PUT instead of POST in your case since you will be replacing the entire content of the file. Take a look at PUT vs POST

> I'll have to know the exact URL to PUT > to

No. You dont have to know the URL to PUT i.e. the PUT URI needn't be present before the PUT operation. If the resource doesn't exist, the resource is created. If the resource is already present, then the resource is replace with the new representation.

To quote the linked article:

> PUT puts a page at a specific URL. If > there’s already a page there, it’s > replaced in toto. If there’s no page > there, a new one is created. This > means it’s like a DELETE followed by > an insert of a new record with the > same primary key

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionworanView Question on Stackoverflow
Solution 1 - PostDonal FellowsView Answer on Stackoverflow
Solution 2 - Postuser1080697View Answer on Stackoverflow
Solution 3 - PostRobert LevyView Answer on Stackoverflow
Solution 4 - PostSuresh KumarView Answer on Stackoverflow