【问题标题】:REST API design for cloning a resource [duplicate]用于克隆资源的 REST API 设计
【发布时间】:2015-08-28 13:41:15
【问题描述】:

我正在使用 swagger 编写 YAML 文档来设计用于克隆资源的 RESTful API 方法。我有几个选择,不知道哪个是最好的。请问有人可以建议吗?

选项:

  1. 放弃将资源对象克隆给消费者的责任(消费者将值分配给新对象的属性,然后创建新对象),该过程需要包含对 API 的两个请求: 对源对象的资源进行 GET,然后对该资源进行 POST 以创建新对象。 感觉消费者的责任太大了
  2. 使用提供 COPY 方法的 WebDAV HTTP 扩展 (see here)。看来这正是我想要克隆的。 但是,我想尽可能地坚持标准方法
  3. 发布到 /{resource}?resourceIdToClone={id} 其中 resourceIdToClone 是可选参数。这将与我已经拥有的用于创建资源的 API 路径冲突,在该路径中我将架构添加到 POST 正文。 这意味着使用 POST 到 /{resource}/ 来创建和克隆,这将违反 SRP。
  4. 添加一个名为 'CloneableResource' 的新资源并执行 POST 到 /CloneableResource/{resource_type}/{resource_source_id}。 对于克隆羊的示例,您将 POST 到 /CloneableResource/Sheep /10。这样,就可以坚持使用标准的 HTTP 方法,不会与任何其他资源路径冲突(或违反 SRP)。但是,我会在域中添加一个新的且可能是多余的类型。我也想不出消费者想要对这个资源执行 POST 以外的任何操作的场景,所以它对我来说似乎是一种代码味道
  5. 针对 /resource/{id}?method=clone 的 GET。这里的优点之一是不需要额外的资源,它可以通过一个简单的可选查询字符串参数来确定。我知道这里的风险之一是,如果 URL 位于网页中,则使用 GET 方法提供发布或删除功能可能很危险,因为它可能会被搜索引擎抓取。

感谢您的帮助!

【问题讨论】:

    标签: api rest post yaml webdav


    【解决方案1】:

    这些选项中的大多数都是非常好的选择。很多只是你最终的风格选择。以下是我对您的每个选项的 cmet。

    1. 将克隆资源对象的责任交给消费者
      一般来说,我对这个解决方案没有真正的问题。对于用户来说,此选项非常易于理解和实施。这可能比提供一些您的用户必须学习如何使用的专有克隆功能更好。

    2. 使用提供 COPY 方法的 WebDAV HTTP 扩展
      我也喜欢坚持标准方法。我不会使用COPY,但如果你这样做我不会感到震惊。

    3. 正在发布到 /{resource}?resourceIdToClone={id}
      这是一个非常好的解决方案。从 REST 的角度来看,您与 API 的其余部分并没有真正的冲突。带有查询参数的 URI 标识的资源与不带查询参数的 URI 不同。查询参数是一种 URI 功能,用于标识无法分层引用的资源。但是,由于大多数 REST 框架的工作方式,可能很难在代码中将它们分开。除了使用诸如/{resource}/clone 之类的分层URI 之外,您可以执行类似的操作。您可以 POST 到此 URI 并在正文中传递 resource_source_id

    4. 添加一个名为“CloneableResource”的新资源并执行 POST 到 /CloneableResource/{resource_type}/{resource_source_id}
      从 REST 的角度来看,这种方法没有任何问题,但我认为添加新类型既不必要又会使 API 混乱。但是,我不同意您的直觉,拥有只有 POST 操作的资源可能会出现问题。它发生了。在现实世界中,并非所有内容都适合 GET、PUT 或 DELETE。

    5. 针对 /resource/{id}?method=clone 的 GET
      这是我不能宽恕的5个选项中的唯一选择。从您的描述看来,您已经明白为什么这是一个坏主意,所以我不确定您为什么要考虑它。但是,要使其成为一个好的解决方案,您所要做的就是将 GET 更改为 POST。然后它变得与#3 解决方案非常相似。 URI 也可以是分层的,而不是使用查询参数。 POST /resource/{id}/clone 也可以。

    我希望这会有所帮助。祝你的决定好运。

    【讨论】:

    • 感谢您考虑杰森。越来越明显的是,这里没有“正确”的答案。希望这个简短的讨论将在未来对其他人有所帮助。
    【解决方案2】:

    如果您想复制资源,那么,是的,复制是一个显而易见的选择。

    (是的,最好将 COPY 和 MOVE 的定义从 RFC 4918 中提取出来,以便从 WebDAV 中解开它们)。

    【讨论】:

    • 感谢您的回复朱利安。这是一个方便的选择,毫无疑问该方法允许消费者做什么。但是,我相信坚持标准 HTTP 方法是目前最好的方法,因为它会简化我的 API 并避免可能以两种不同的方式实现相同结果的情况(通过使用 COPY 或通过对资源执行 GET,然后执行 POST)。我更愿意将消费者限制为通过我的 API 实现资源克隆的单一、一致的方法
    【解决方案3】:

    受项目要求和团队成员偏好范围的影响,选项 1 将在此阶段为我们提供最佳服务。

    • 符合标准 HTTP 方法将简化和阐明我的 API
    • 将有一个单一的、一致的方法来克隆资源。这超过了我将克隆工作指定给消费者的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 2021-09-02
      • 2020-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多