如何使用REST建模文件系统操作?

时间:2010-05-18 19:34:10

标签: file rest filesystems

对于某些文件系统的基本操作(例如lsrm),有明显的对应物,但是如何实现不直接的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方式实现复制,移动或其他文件系统操作?还是有正确的方法?我做错了吗?

6 个答案:

答案 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?

  • 不会将“移动”或“复制”附加到URI(即RPC)
  • 它使用PUT(POST将附加到集合,目标URI未完全知晓)
  • 它不使用发送的“命令”(例如XML指令),这是RPC而不是REST。
  • 不了解下划线存储 - 客户端不关心硬/软链接或写时复制优化,也不应该知道它们。
迈克·布朗

答案 1 :(得分:3)

  

[...首选的实施方式   cp将包括GETting资源,   删除它并再次将其丢回   用一个新的名字。]

上述方法的一个问题是缺乏原子性和一致性。由于每个操作(GET,DELETE和PUT)都通过HTTP(本质上是无状态的)发生,因此服务器无法强制执行原子性。出于任何原因,客户端可能会在最后一步之前的任何步骤之后中止,这会使服务器的数据状态不一致。

可行的方法:

  • 如果资源是文档(我猜,它们就在你的情况下),我会探索使用WebDAV的选项。
  • 如果WebDAV不是一个选项 -
    • 在服务器上创建一个控制器对象来管理复制和移动操作,客户端可以POST到/ videos / my_videos / [video_id] / copy
    • 之类的东西
    • 在您的回复中,您可以在以下行中指定复制资源的URI:
  

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解决您的问题。