2017-07-19 40 views
0

我想知道当您拥有包含子资源列表的资源时,哪个是最佳实践。例如,您拥有资源作者,其中包含名称,ID,生日和List书籍等信息。这本书目录只与作者有关​​。所以,你有以下情形:从子资源列表中更新/添加/删除项目的REST设计

  1. 你想要一本新书添加到图书清单
  2. 你想从列表中
  3. 更新一本书的名字要从删除一本书列表

SOLUTION 1

我搜遍这是正确的设计,我发现了多种方法。我想知道是否有标准的设计方法。我认为设计的书上说来有以下几种方法:

  1. 补充:POST /authors/{authorId}/book/
  2. 更新:PUT /authors/{authorId}/book/{bookId}
  3. 删除:DELETE /authors/{authorId}/book/{bookId}

解决方案2

我的解决方案是只有一个PUT方法完成所有这三件事情,因为书籍列表只存在于对象作者中,而您是实际的更新作者。喜欢的东西:

PUT /authors/{authorId}/updateBookList(发送author对象内部的整体更新的图书列表)

我发现在我的方案的多个错误。例如,从客户端发送更多数据,在客户端拥有一些逻辑,对API进行更多验证,并且还依赖客户端具有最新版本的Book List。

我的问题是:这是否反模式?

情况1.在我的情况下,我的API使用另一个API,而不是数据库。使用的API只有一个“updateBookList”方法,所以我猜测在我的API中复制这种行为也比较容易。这是否正确?

情况2.但是,假设我的API会使用数据库,它会更适合使用SOLUTION 1吗?

此外,如果你可以提供一些文章,书籍,你可以找到类似的信息。我知道这种设计不是用石头写的,但有些指导方针会有所帮助。 (例如:REST API Design Rulebook

+0

如果这是一个真正的问题,而不是作业,请记住,书籍可以有多个作者。一本书应该是真正的顶级资源。 –

+0

这是一个真正的问题,但在我的情况下,书籍列表只属于一个作者。例如,如果您删除作者,那些书籍将不再存在。 – green

+0

现在。如果业务需求发生变化,您可能会冒API风险。当然,只有你可以知道这有多可能。 –

回答

2

我会去第一个选项,并有单独的方法,而不是堵塞一般PUT内的所有逻辑。即使您依赖的是API而不是数据库,也只是第三方依赖关系,您应该可以随时切换,而不必重构太多的代码。

话虽这么说,如果你要允许大量的书籍一次的更新,然后PATCH可能是您的朋友:

RFC 6902展望(定义修补程序标准),从客户端的角度来看,API可以被称为像

PATCH /authors/{authorId}/book 
[ 
    { "op": "add", "path": "/ids", "value": [ "24", "27", "35" ]}, 
    { "op": "remove", "path": "/ids", "value": [ "20", "30" ]} 
] 
2

解决方案2听起来很像老式的RPC在方法被调用执行一些处理。这就像一个REST反模式,因为REST的重点是资源而不是方法。你可以在资源上执行的操作是由底层协议(在你的情况下是HTTP)给出的,因此REST应该遵守底层协议的语义(它的几个约束之一)。

此外,REST并不在乎您如何设置您的URI,因此实际上没有RESTful URL。对于自动化系统,遵循特定结构的URI与作为URI的随机生成的字符串具有相同的语义。尽管应用程序应该使用rel属性,它给了URI一些应用程序可以使用的逻辑名称。一个期望URL的某种逻辑组合的应用程序已经与API紧密耦合,因此违反了REST试图解决的原则,即客户端与服务器API的解耦。

如果您想通过PUT以REST方式更新(子)资源,您必须遵循put的语义,它基本上声明接收到的有效内容会替换在更新之前在给定的URI处可访问的有效内容。

PUT方法要求该目标资源的状态是 创建取代与由封闭在所述请求消息的有效载荷的表示 定义的状态。

...

在POST请求中的目标资源旨在根据资源的自己的语义来处理 封闭表示, 而在PUT请求封闭表示被定义为 更换状态的目标资源。因此,PUT 的意图对于中间人来说是幂等的和可见的,尽管确切的 效果只能由原始服务器知道。

在问候部分更新RFC 7231指出部分更新是可能的,通过使用PATCH或者通过@Alexandru或通过直接在子资源发出PUT请求,其中所述有效载荷替换子资源的内容的建议与有效载荷中的一个相关联。对于包含子资源的资源,这会影响部分更新。

部分内容更新是可能的通过 靶向与状态的单独识别的资源重叠的较大的资源的 部分,或通过使用 已经为部分更新被特别定义(例如,不同的方法,所述 [RFC5789]中定义的PATCH方法)。

在你的情况,你可以因此直接通过PUT操作发送更新的书籍收藏的东西像一个.../author/{authorId}/books资源取代了旧的集合。因为这可能不适合那些写过很多出版物的作者PATCH可能更好。但请注意,PATCH需要原子和事务性行为。要么所有的行动都成功,要么没有。如果在操作的中间发生错误,则必须将所有已执行的步骤作为角色。

关于您对进一步文献的要求,SO并不是正确的地方要问这个问题,因为这里有一个自己的离题关闭/标记原因。