用于克隆资源的REST API设计

dev*_*v'd 9 api rest post yaml webdav

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

选项:

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

谢谢你的帮助!

Jas*_*ers 11

大多数这些选择都是非常好的选择.很多只是你的风格选择到底.以下是我对每个选项的评论.

  1. 放弃将资源对象克隆到消费者的责任
    通常我对此解决方案没有任何问题.该选项对于用户理解和实施非常简单.它可能比提出一些用户必须学习如何使用的专有克隆功能更好.

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

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

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

  5. 对/ resource/{id}进行GET?方法=克隆
    这是我唯一不能容忍的选项.从你的描述看来,你已经明白为什么这是一个坏主意,所以我不确定你为什么要考虑它.但是,要使其成为一个好的解决方案,您所要做的就是将GET更改为POST.然后它变得非常类似于#3解决方案.URI也可以是分层的,而不是使用查询参数. POST /resource/{id}/clone也会起作用.

我希望这可以帮到你.祝你的决定好运.


dev*_*v'd 4

受项目要求和团队成员偏好范围的影响,选项 1 在现阶段最适合我们。

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