REST API设计:克隆资源

11

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

选项:

  1. 将克隆资源对象的责任交给消费者(其中消费者分配新对象的属性值,然后创建新对象),该过程需要包括两个针对API的请求:针对源对象进行GET,然后是一个POST到该资源上用于创建新的对象。这感觉像是在消费者那里承担了太多责任
  2. 使用WebDAV HTTP扩展提供的COPY方法 (见此处)。看起来这正是我想要的复制功能。但是,我想尽可能地坚持标准方法
  3. 在/{resource}?resourceIdToClone={id}上进行POST,其中resourceIdToClone是可选参数。这将与我已经有的用于创建资源的API路径冲突,在其中向POST主体添加模式。 这意味着在/{resource}/上使用POST进行创建和克隆,这将违反SRP。
  4. 添加一个名为' CloneableResource '的新资源,并对/CloneableResource/{resource_type}/{resource_source_id}执行POST操作。例如,如果要克隆一只绵羊,则可以向/CloneableResource/Sheep/10进行POST。这样,就可以坚持使用标准的HTTP方法,不会与任何其他资源路径冲突(或违反SRP)。但是,我将添加一个新的、可能多余的类型到域中。我也想不到有什么情况下消费者会希望执行除了POST之外的其他操作,所以这个似乎是代码异味
  • 对/resource/{id}?method=clone的GET请求。其中一个优点是不需要额外的资源,并且可以通过简单的可选查询字符串参数确定。我知道这里的一个风险是,如果URL在网页上,则使用GET方法提供post或delete功能可能会被搜索引擎爬取。
  • 3个回答

    12
    大多数选项都是完全可行的选择。最终很大程度上取决于您的风格选择。以下是我对每个选项的评论。
    1. 将克隆资源对象的责任交给消费者
    一般来说,我对这个解决方案并没有太多问题。这个选项非常直观易懂,用户可以轻松实现。这可能比想出一些专有的克隆功能更好,因为您的用户不必学习如何使用它们。
    2. 使用WebDAV HTTP扩展提供的COPY方法
    我也喜欢坚持标准方法。我不会使用“COPY”,但如果您使用了,我也不会感到惊讶。
    3. 对/{resource}进行POST,同时传递查询参数resourceIdToClone={id}
    这是一个完全可行的解决方案。从REST的角度来看,您与API的其余部分没有冲突。带有查询参数的URI识别不同于没有查询参数的URI的资源。查询参数是用于标识无法按层次结构引用的资源的URI特性。然而,由于大多数REST框架的工作方式,将它们分开可能会很困难。您可以执行类似的操作,只是使用分层URI,例如/{resource}/clone。您可以对此URI进行POST,并在正文中传递resource_source_id。
    4. 添加一个名为“CloneableResource”的新资源,并对/CloneableResource/{resource_type}/{resource_source_id}执行POST
    从REST的角度来看,这种方法没有问题,但我认为添加一个新类型既不必要又会使API变得凌乱。但是,我不同意您的直觉认为只有一项POST操作的资源可能会存在问题。这种情况很常见。在现实世界中,并不是所有东西都能很好地适应GET、PUT或DELETE。
    5. 对/resource/{id}?method=clone进行GET这是5个选项中唯一一个我无法支持的选项。从您的描述中可以看出,您已经理解为什么这是一个不好的想法,所以我不确定为什么您正在考虑它。但是,要使其成为一个好的解决方案,您只需将GET更改为POST。它将变得非常类似于第3种解决方案。URI也可以采用分层方式,而不是使用查询参数。POST /resource/{id}/clone同样可行。

    希望这对您有所帮助。祝您在做出决定时好运。


    感谢您的考虑,Jason。越来越明显的是,在这里没有“正确”的答案。希望这个简短的讨论能够帮助未来的其他人。 - dev'd

    4
    如果您想复制一个资源,那么COPY是一个显而易见的选择。(是的,从RFC 4918中提取COPY和MOVE的定义以将它们与WebDAV分离开来会很好。)

    感谢您的回复Julian。这是一个方便的选项,方法允许消费者做什么毫无疑问。然而,我认为现在坚持标准的HTTP方法是最好的方式,因为它会简化我的API,并避免可能通过两种不同的方式实现相同结果(使用COPY克隆资源或对资源执行GET然后POST)。我更喜欢限制消费者只能通过我的API来实现单一且一致的资源克隆方法。 - dev'd

    3

    受项目要求和团队成员的不同喜好影响,目前选项1最适合我们。

    • 遵循标准的HTTP方法将简化并澄清我的API。
    • 将有一个单一、一致的方法来克隆资源。这比我对指定克隆工作给消费者的问题更重要。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接