【问题标题】:How to model file system operations with REST?如何使用 REST 对文件系统操作进行建模?
【发布时间】:2010-05-18 19:34:09
【问题描述】:

对于某些文件系统的基本操作(例如lsrm)有明显的对应物,但是您将如何实现不直接的RESTful 操作,例如cpmv

正如对How to implement copy paste of a resource in REST? 问题的回答所建议的那样,实现cp 的首选方法包括获取资源、删除资源并用新名称重新放回资源。

但是如果我需要高效地做这件事呢?例如,如果资源的大小会很大?我将如何消除将资源的有效负载多余地传输到客户端并返回到原始服务器?

这是一个插图。我有一个资源:

/videos/my_videos/2-gigabyte-video.avi

我想将它复制到一个新资源中:

/videos/johns_videos/copied-2-gigabyte-video.avi

如何以 RESTful 方式实现复制、移动或其他文件系统操作?或者有没有合适的方法?我做错了吗?

【问题讨论】:

    标签: file rest filesystems


    【解决方案1】:

    我不相信任何给定的答案都是 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/copied-2-gigabyte-video.avi) 的位置 (/videos/johns_videos/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 不完全已知)
    • 它不使用 RPC 而非 REST 发送的“命令”(例如 XML 指令)。
    • 不了解下划线存储 - 客户端不关心硬/软链接或复制优化,也不应该知道它们。

    迈克·布朗

    【讨论】:

      【解决方案2】:

      [...实现的首选方式 cp 将包括获取资源, 删除并重新放回 用一个新名字。]

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

      一种可能的方法:

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

      HTTP/1.1 201 创建

      内容类型:video/x-msvideo

      位置:/videos/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 标记发送到客户端,客户端将其连同其请求一起发送。仅当该值仍然一致时,服务器才会执行复制/移动操作。这将解决在您的复制/移动操作仍在进行时更改资源的并发问题。

      【讨论】:

      • 我喜欢你的方法 - 我会看看我是否可以使用 Webdav。在您的另一种方法中,URL“/videos/my_videos/[video_id]/copy”中名为 copy 的资源不会将操作编码到与 REST 原则相反的 URL 中吗?
      • @massive -- 1. 当然看看 WebDAV 是否​​适用于这种情况(我认为这是量身定制的) 2. 复制/移动作为资源不违反任何 REST 原则。仅将资源视为“事物”或领域对象只会在一定程度上影响我们。为了更实际的目的,您需要将处理函数作为资源(例如:计算保费、两个银行账户之间的转账金额等)。这是 RESTful Web Services Cookbook (O'reilly) 中很好地讨论的一种模式。如果您有任何疑问,我很乐意进一步讨论。
      • 我在这里看不到多少是 RESTful 的(也许没关系)。不涉及超媒体(没有链接可跟踪),并且您需要知道 ../copy URI 甚至存在的带外信息。
      【解决方案3】:

      您可以公开一个新服务,该服务接受 (POST) 一个简单的 xml 文档,概述您想要做什么。

      <move>
         <target>/videos/my_videos/2-gigabyte-video.avi</target>
         <destination>/videos/johns_videos/copied-2-gigabyte-video.avi<destination>
      <move>
      

      然后这个服务可以返回一个URI,客户端可以去那里检查操作的状态。然后客户端可以与该新资源进行交互,如果仍处于未决状态则取消移动,或者检查它是否成功。

      【讨论】:

      • 但这不是真的意味着您将操作的含义编码到消息中吗?
      • 一点也不。您的消息正在改变系统的状态,这确实是 HATEOAS 的定义。您将如何撰写毫无意义的信息?
      • 好的,我明白你的意思了。我只是对在消息中编码操作感到不安,因为它让我想起了 RPC 样式的 Web 服务(例如 SOAP),您将操作(移动)封装在信封中并将其发送到通用端点。理解此类消息的含义的唯一方法是解析它并理解它的语义,这似乎不是很 RESTful。再说一次,如果我只使用四个基本的 HTTP 动词,可能就没有完美的解决方案。
      • 这与每个人总是引用的“RESTbucks - 如何以 RESTfully 方式订购一杯咖啡”(或其他任何名称)示例真的没有什么不同。您正在向队列提交作业,获取响应(以及指向其他资源的链接)。您的客户只需要了解您定义的超媒体格式,然后按照链接的数据图得出结果。
      【解决方案4】:

      执行此操作的一种方法是制定 PUT/POST 请求,以便您可以提供实际数据或提供资源的 URL,可能还可以选择创建硬链接或符号链接。如果给定的 URL 托管在您自己的系统上,那么您可以简单地在内部指向同一个文件,可能会保留一些“写时复制”或类似的内容以使其高效。

      【讨论】:

        【解决方案5】:

        在我看来,视频是一种资源。所以这个资源有一个路径。如果您执行 UPDATE 更改资源路径怎么办?

        然后,在你的代码中,如果它改变了路径,你只需要移动文件。

        【讨论】:

        • 您建议如何使用 UPDATE 更改路径?当然,如果我的资源在其表示中有路径,那么我可以更改表示,但如果没有,那么我就没有想法了。
        【解决方案6】:

        REST 不限于 HTTP!最好的方法是使用 webdav 来解决您的问题。

        【讨论】:

          猜你喜欢
          • 2014-07-10
          • 2011-12-30
          • 1970-01-01
          • 2018-06-23
          • 1970-01-01
          • 2018-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多