我正在尝试设计一个类似于RESTful文件系统的服务,而复制/移动操作给我带来了一些麻烦。
首先,上传一个新文件是使用PUT到文件的最终URL:
PUT /folders/42/contents/<name>
问题是,如果新文件已经驻留在系统上的不同URL下,该怎么办?
复制/移动想法1:自定义标题的PUT。
这类似于S3's copy。一个看起来和上传一样的PUT,但是有一个自定义的头:
PUT /folders/42/contents/<name>
X-custom-source: /files/5
这很好,因为在复制/移动时很容易更改文件名。然而,S3不提供移动操作,可能是因为使用此方案的移动不是幂等的。
复制/移动想法2:POST到父文件夹。
这类似于Google的URL复制。一个POST到目标文件夹,其中包含描述源文件的XML内容:
POST /folders/42/contents
...
<source>/files/5</source>
<newName>foo</newName>
我也许可以通过POST到文件的新URL来改变它的名称.
最终,我在寻找一些易于使用和理解的东西,所以除了对上述内容的批评,新的想法当然是受欢迎的!
5条答案
按热度按时间fumotvh31#
HTTP规范规定,如果资源已经存在,则更新资源并返回200。如果资源不存在,则创建资源并返回201。
编辑:
好吧,我误解了。我更喜欢POST而不是父文件夹的方法。你也可以使用查询字符串参数来引用源文件。
628mspwn2#
要创建一个新的资源,你通常使用
POST
。这应该在服务器创建的URI上创建一个新的资源。REST的意思是,在
POST
中,新的Resource位于服务器确定的路径中。这就是复制在(windows)FileSystem中的工作方式。考虑到您将文件复制到已经存在的名称,那么上面示例的响应可能是:然后通过先复制再删除来进行移动。您不应该在一个请求中执行这两个操作。
编辑:
我觉得这本书RESTful Web Services Cookbook非常好。
第11章介绍了Copy方法,并在11.1中提出了以下建议:
问题您想知道如何复制现有资源。
解决方案设计一个可以创建副本的控制器资源,客户端向该控制器发出POST请求,请求复制资源。要使POST条件化,请向客户端提供一次性URI。控制器创建副本后,返回响应代码201(Created),其中包含一个Location头,该头包含副本的URI。
请求POST /albums/2009/08/1011/duplicate;t= a5 d 0 e32 ddff 373 df 1b 3351 e53 fc 6 ffb 1
回复
7uhlpewt3#
REST并不局限于默认的HTTP方法集。在这种情况下,您可以使用WebDAV。
vi4fp9gy4#
对于移动,你可以
a).通过PUT进行复制,使用自定义源头,后跟源上的一个标记。
B)带有自定义移动标头的. css源。
我更喜欢后者,因为它可以是原子的,并且客户端很清楚资源已从原始集合中删除。当它将集合定位到新位置时,它会在那里找到移动的资源。
ej83mcc05#
对于移动部分,如果你想保持简单,只需执行复制(PUT)然后删除的组合。