RESTful复制/移动操作?

时间:2010-06-10 18:06:15

标签: web-services rest

我正在尝试设计类似RESTful文件系统的服务,而复制/移动操作会给我带来一些麻烦。

首先,使用PUT到文件的最终URL上传新文件:

PUT /folders/42/contents/<name>

问题是,如果新文件已经在不同的URL下驻留在系统上怎么办?

复制/移动Idea 1 :使用自定义标头进行PUT。

这类似于S3's copy。 PUT看起来与上传相同,但带有自定义标题:

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

这很好,因为在复制/移动时很容易更改文件的名称。但是,S3不提供移动操作,可能是因为使用此方案的移动不是幂等的。

复制/移动Idea 2 :POST到父文件夹。

这类似于Google Docs copy。 POST目标文件夹,其中包含描述源文件的XML内容:

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

我或许可以POST到文件的新URL来更改其名称..?否则,我不得不在XML内容中指定一个新名称,这会放大这个想法的RPCness。它也与想法1的上传操作不一致。

最终我正在寻找易于使用和理解的东西,所以除了对上述内容的批评之外,当然欢迎新的想法!

5 个答案:

答案 0 :(得分:6)

要创建新资源,通常使用POST。这应该在服务器创建的URI上创建一个新资源。

POST /folders/42/contents/fileName
<target>newFile</target>

REST说的是POST新资源位于服务器确定的路径中。这就是复制甚至在(windows)文件系统中的工作方式。考虑将文件复制到已存在的名称,然后上述示例的响应可能是:

<newFileLocation>/folders/42/contents/newFile-2</newFileLocation>

然后通过第一次复制然后删除进行移动。您不应该在一个请求中执行这两个操作。

修改
我发现这本书RESTful Web Services Cookbook非常好。

第11章处理Copy方法,并在11.1中推荐以下内容:

  

问题您想知道如何制作现有资源的副本。

     

解决方案设计可以创建副本的控制器资源。客户端向此控制器发出POST请求以复制   资源。要使POST成为条件,请为其提供一次性URI   客户。控制器创建副本后,返回响应代码   201(已创建),其中包含副本的URI的Location标头。

     

请求 POST / albums / 2009/08 / 1011 / duplicate; t = a5d0e32ddff373df1b3351e53fc6ffb1

     

回复

<album xmlns:atom="http://www.w3.org/2005/Atom">
<id>urn:example:album:1014</id>
<atom:link rel="self" href="http://www.example.org/albums/2009/08/1014"/>
...
</album>

答案 1 :(得分:4)

HTTP规范说如果资源已经存在,那么您更新资源并返回200。 如果资源不存在,那么您创建它并返回201。

编辑:
好的,我误读了。我更喜欢POST到父文件夹的方法。您还可以使用查询字符串参数来引用源文件。 e.g。

POST /destination/folder?sourceFile=/source/folder/filename.txt

答案 2 :(得分:4)

REST不限于默认的HTTP方法集。在这种情况下你可以使用WebDAV。

答案 3 :(得分:0)

对于移动部分,如果要保持简单,只需复制(PUT)然后删除组合。

答案 4 :(得分:0)

移动时,你可以

A)。通过PUT复制自定义源标题,然后在源上删除。

B)。使用自定义移动标题删除源。

我更喜欢后者,因为它可以是原子的,客户很清楚资源是从原始集合中删除的。当它获取新位置的集合时,它将在那里找到移动的资源。