22

我有一个可以通过 URI 访问的资源,/resources/{resource_identifier}并且它有一个我希望可以访问的“状态”属性。我为此想到了几个选项,哪个是“最好的”或“最完整的”?

选项一将操作附加到 URI 并将客户端POST添加到这些 URI

/resources/{resource_identifier}/void    
/resources/{resource_identifier}/open    
/resources/{resource_identifier}/close

不过这看起来很笨拙。


选项二在 URI 中使用查询参数并让客户端PATCH访问这些

/resources/{resource_identifier}?transition=void
/resources/{resource_identifier}?transition=open
/resources/{resource_identifier}?transition=close

选项三使用请求的有效负载并拥有客户端PUT

/resources/{resource_identifier}

有效载荷选项:

{ ..., "status" :"void" }
{ ..., "status" :"open" }
{ ..., "status" :"close" }

或者也许完全是别的东西?

4

6 回答 6

32

第一个选项显然不是 REST;您在 URI 中有“操作”并且正在使用POST,这是创建一个新资源,您显然没有尝试这样做。

现在只看 URI 格式。选项二越来越好,但这种性质的查询字符串更适合读取数据。没有什么能真正阻止你这样做。选项三具有最佳 URI 格式,它仅引用您要在请求中引用的资源。

如果我们现在考虑请求的方法。在我的书中,这很简单,我假设状态只是这个资源的一个字段,所以如果你只是做部分更新,你就是在修补资源,因此PATCH是使用的方法。如果“状态”是唯一的属性,那么改变状态就是完全改变资源,因此PUT是可以接受的;但我怀疑情况是否真的如此。

就目前而言,第三个选项的 URI 与使用的结合PATCH可能是最好的选择。

PATCH /resources/{resource_identifier}

{ "status" :"close" }

当然,您也可以将其与通过它们自己的 URI 公开特定属性的概念结合起来,就好像它们本身就是一种资源一样。坦率地说,我不喜欢这样,因为它感觉很奇怪,并且一次只适用于一个属性。不过,如果这是你想要使用的,你可以有类似的东西:

PUT /resources/{resource_identifier}/status

close

请记住,没有“正确”的 REST 方式,只有“不错”的方式。这是一种风格,而不是一套规则。

我还建议您考虑,一般来说,能够采用多种格式是一个理想的功能。因此,第一个选项往往更容易使用。您可以像示例一样采用 JSON,或者将其交换为 XML<status>close</ status>或简单的键值对status=closed等。

于 2015-07-20T14:30:23.970 回答
16

Why not have 'status' as resource. You can manage it. Also assume that there should be already a 'status' created as part of the {resource_identifier} resource creation and there is already a default value for the status.

Then the business logic need is just to 'update' the status via the rest call and therefore 'PUT' should be used.

updated Moving status to the Put-Body

PUT:    /resources/{resource_identifier}/status/

Body: {void | open | close }
于 2013-08-14T17:54:01.297 回答
1

您的第二个选项看起来更好,因为您要维护 RESTful url 结构,而不是将 RPC 样式的方法附加到它的末尾。

为什么不这样做:

PUT并随请求/resources/:id发送数据。transition=void

它的行为方式与您接收 POST 请求时的行为方式相同,只需从请求正文中获取数据即可。

于 2013-08-14T15:10:55.717 回答
1

状态变化有很多业务逻辑的情况很多。虽然答案基于“休息标准”,但我认为有些情况不仅仅是改变状态字段。

例如,如果系统必须取消订单。这不仅仅是改变一个状态,因为订单有很多状态,每次改变都代表了很多逻辑(通知、验证等)

在使用的情况下:

PATCH /order/1
{ "status" :"cancelled" }

我可以向你保证,逻辑会被客户端和服务端分散,很难维护,而且不会有优雅的代码(尤其是在服务端,它会验证之前、之后的状态,如果更改是一致的,并且会与更新责任混在一起)。

我认为有一个取消方法并完成它的工作更简单。我认为在很多情况下这样做更优雅:

PATCH: /order/1/cancel 

//you could use the body with some cancellation data.

以下链接可以帮助您:https ://phauer.com/2015/restful-api-design-best-practices/#keep-business-logic-on-the-server-side

于 2019-08-08T22:22:39.570 回答
0

在我自己看来,我使用了这里普遍同意的两种结构。但是,以下是我如何画线。

在对资源的属性进行更新具有副作用的情况下(例如,如果属性的值为 XYZ,则发送邮件),我使其具有自己的资源(即端点。例如PUT /resources/:id/status),这将简化控制器处的事情等级。否则,我会使用其父 ( PATCH /resources/:id/status)的资源

于 2021-08-09T13:11:33.970 回答
0

由于 PUT、GET 和 DELETE 的标准行为大致映射到 CRUD 范式,一些人认为资源 API 应该只用于 CRUD 用例。然而,这是一个不正确的评估,因为 POST 可用于执行不能很好地映射到 CRUD 的行为。

于 2020-07-02T10:46:55.053 回答