views:

62

answers:

3

I am trying to design a RESTful filesystem-like service, and copy/move operations are causing me some trouble.

First of all, uploading a new file is done using a PUT to the file's ultimate URL:

PUT /folders/42/contents/<name>

The question is, what if the new file already resides on the system under a different URL?

Copy/move Idea 1: PUTs with custom headers.

This is similar to S3's copy. A PUT that looks the same as the upload, but with a custom header:

PUT /folders/42/contents/<name>
X-custom-source: /files/5

This is nice because it's easy to change the file's name at copy/move time. However, S3 doesn't offer a move operation, perhaps because a move using this scheme won't be idempotent.

Copy/move Idea 2: POST to parent folder.

This is similar to the Google Docs copy. A POST to the destination folder with XML content describing the source file:

POST /folders/42/contents
...
<source>/files/5</source>
<newName>foo</newName>

I might be able to POST to the file's new URL to change its name..? Otherwise I'm stuck with specifying a new name in the XML content, which amplifies the RPCness of this idea. It's also not as consistent with the upload operation as idea 1.

Ultimately I'm looking for something that's easy to use and understand, so in addition to criticism of the above, new ideas are certainly welcome!

+1  A: 

The HTTP spec says if the resource already exists then you update the resource and return 200. If the resource doesn't exist then you create it and you return 201.

Edit:
Ok, I misread. I prefer the POST to the parent folder approach. You could also refer to the source file using a query string parameter. e.g.

POST /destination/folder?sourceFile=/source/folder/filename.txt
Darrel Miller
Sorry, I meant what if the new file already resides on the system at a different URL. That is, I don't want to re-upload the file. I just want it relocated.
ladenedge
We went with a POST to the parent container. It seemed to be the method that was most easily understood by newcomers. Thanks for the ideas!
ladenedge
A: 

For the move part, just do a combo of Copy (PUT) then Delete if you want to keep it simple.

redben
It's a fair idea, but it feels like copy and move work essentially the same way here; I'm not sure deconstructing move buys me much. :-(
ladenedge
+1  A: 

REST is not limited to the default set of HTTP methods. You could use WebDAV in this case.

deamon
That's an interesting idea! I'll have to look into this.
ladenedge