对于某些文件系统的基本操作(例如ls
和rm
),有明显的对应物,但是如何实现不直接的RESTful操作,例如cp
或{{ 1}}?
作为问题How to implement copy paste of a resource in REST?的答案提示,实施mv
的首选方式包括获取资源,删除资源并使用新名称将其重新打包。
但如果我需要有效地做呢?例如,如果资源的规模很大?如何消除资源有效负载到客户端和返回原始服务器的多余传输?
这是一个例子。我有一个资源:
/videos/my_videos/2-gigabyte-video.avi
我希望将其复制到新资源中:
/videos/johns_videos/copied-2-gigabyte-video.avi
如何以RESTful方式实现复制,移动或其他文件系统操作?还是有正确的方法?我做错了吗?
答案 0 :(得分:5)
我不相信任何给定的答案都是RESTful。这就是我要做的。
复制:
PUT /videos/johns_videos/copied-2-gigabyte-video.avi
HOST: www.server.com
Content-Location: /videos/johns_videos/2-gigabyte-video.avi
[empty-body]
将内容放在(/videos/johns_videos/2-gigabyte-video.avi)的位置(/videos/johns_videos/copied-2-gigabyte-video.avi)。
移动将是带删除的副本,为了检查复制和删除之间的一致性,您需要使用在PUT的响应中给出的修订号。
PUT /videos/johns_videos/copied-2-gigabyte-video.avi
HOST: www.server.com
Content-Location: /videos/johns_videos/2-gigabyte-video.avi
[empty-body]
201 Created
ETag: "3e32f5a1123afb12" (an md5 of the file)
Location: /videos/johns_videos/copied-2-gigabyte-video.avi
[empty-body]
DELETE /videos/johns_videos/2-gigabyte-video.avi
HOST: www.server.com
If-Match: "3e32f5a1123afb12"
[empty-body]
204 No Content
[empty-body]
为什么这个RESTful?
答案 1 :(得分:3)
[...首选的实施方式 cp将包括GETting资源, 删除它并再次将其丢回 用一个新的名字。]
上述方法的一个问题是缺乏原子性和一致性。由于每个操作(GET,DELETE和PUT)都通过HTTP(本质上是无状态的)发生,因此服务器无法强制执行原子性。出于任何原因,客户端可能会在最后一步之前的任何步骤之后中止,这会使服务器的数据状态不一致。
可行的方法:
HTTP / 1.1 201已创建
内容类型:video / x-msvideo
位置:/视频/ johns_videos / 8765
注意:我更喜欢发回ID并使用资源ID而非
位置: /videos/johns_videos/copied-2-gigabyte-video.avi
移动操作非常相似,只是服务器可以接受目标资源。例如:
http://example.com//videos/johns_videos/8765/move?destination=[destination]
您可以扩展上述方法,使服务器向客户端发送Last-Modified标记,客户端将其与请求一起发送。仅当该值仍然一致时,服务器才会执行复制/移动操作。这将解决在复制/移动操作仍在进行时正在更改的资源的并发问题。
答案 2 :(得分:1)
您可以公开一个新服务(POST)一个简单的xml文档,该文档概述了您想要做的事情。
<move>
<target>/videos/my_videos/2-gigabyte-video.avi</target>
<destination>/videos/johns_videos/copied-2-gigabyte-video.avi<destination>
<move>
然后,此服务可以返回客户端可以访问的URI并检查操作的状态。然后,客户端可以与该新资源进行交互,如果仍然未决,则取消该移动,或检查其是否成功。
答案 3 :(得分:0)
我认为,视频是一种资源。所以这个资源有一条路径。如果你做一个更改资源路径的UPDATE怎么办?
然后,在您的代码中,如果它改变了路径,您只需移动文件。
答案 4 :(得分:0)
执行此操作的一种方法是制定您的PUT / POST请求,以便您可以提供实际数据或提供资源的URL,可能还可以选择创建硬链接或符号链接。如果给定的URL托管在您自己的系统上,那么您可以简单地在内部指向同一个文件,可能保留一点“写入时复制”或沿着这些行,以使其有效。
答案 5 :(得分:0)
REST不仅限于HTTP!最好的方法是使用webdav解决您的问题。