RESTful API:更新实体时 return 会产生副作用
RESTful APIs: what to return when updating an entity produces side-effects
我们 API 中的一个拥有 tasks
资源。 API 的消费者可以根据需要创建、删除和更新给定任务。
如果任务完成(即,其状态通过 PUT /tasks/<id>
更改),则可能会自动创建一个新任务 。
我们正在努力保留它 RESTful。告诉调用用户已创建新任务的正确方法是什么?我想到了以下解决方案,但我认为它们都有缺点:
- 在
PUT
响应中包含一个附加字段,其中包含有关最终新任务的信息。
- Return 仅更新任务,并期望用户调用
GET /tasks
以检查是否已创建任何新任务。
选项 1 在我看来打破了 RESTful-ness,因为 API 预计 return 仅关于更新实体的信息。选项 2 希望用户做一些事情,但如果他不做,那么没有人会意识到创建了一个新任务。
谢谢。
更新: PUT
在更新任务的完整 JSON 表示中调用 return HTTP 200 代码。
@tophallen 建议有一个任务树,这样(如果我做对了)选项 2 中的 returned 实体包含新任务作为直接子任务。
您确实有 2 个选项和 200 个状态 PUT,您可以执行 headers(如果您这样做,请查看 this post)。当然不是一个坏的选择,但你会想要确保它被规范化 site-wide,有据可查,并且你没有任何东西,例如 firewalls/F5's/etc/ re-writing 你的 headers.
虽然这样的事情是一个公平的选择:
HTTP/1.1 200 OK
Related-Tasks: /tasks/11;/tasks/12
{ ...task response... }
或者您必须在响应中向客户提供一些指示 body。您可以有一个支持 child 任务的任务结构,或者您可以规范化所有响应以包含 "meta" 东西的空间,即
HTTP/1.1 200 OK
{
"data": { ...the task },
"related_tasks": [],
"aggregate_status": "PartiallyComplete"
}
像这样的东西随处可见(有点工作,因为听起来你不只是开始这个项目)可能非常有用,因为你也可以将它用于分页等场景。
就我个人而言,我认为如果你让 related_tasks
属性 只包含调用 child 任务的路由,或者调用 id,那可能是最好的、更轻松的响应,因为客户可能并不总是关心立即打电话检查所说的 child-task。
编辑:
实际上,我考虑得越多 - 在您的情况下 header 越有意义 - 因为客户端可以在任务处理期间的任何时候更新任务,所以可能有也可能没有 child 任务在进行中 - 因此当 child 任务开始时修改 off-chance 客户端调用以更新任务的数据结构似乎工作多于好处。 header 将允许您轻松添加 child 任务并在 任何 点通知用户 - 您可以对 POST 应用相同的事情恰好立即完成并启动 child 任务等的任务。它可以轻松支持多个任务。我认为这也使它保持最多 restful 并减少了服务器调用,客户端将始终能够知道流程链中发生了什么。 header 的细节可以定义,但我相信在这种情况下更传统的做法是让它指向资源,而不是 within 资源的键。
如果还有其他选择,我很想听听。
看起来你很在意RESTful,但你没有使用HATEOAS,这是矛盾的。如果您使用 HATEOAS,则相关实体只是另一个 link,客户可以随意关注它们。您所拥有的在 REST 中没有问题。如果这对您来说听起来很陌生,请阅读以下内容:http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Option 1 breaks the RESTful-ness in my opinion, since the API is
expected to return only information regarding the updated entity.
这不是真的。 API 预计 return 任何被记录为该媒体类型可用信息的内容。如果您记录了一个任务有一个用于相关副作用任务的字段,那么它没有任何问题。
我们 API 中的一个拥有 tasks
资源。 API 的消费者可以根据需要创建、删除和更新给定任务。
如果任务完成(即,其状态通过 PUT /tasks/<id>
更改),则可能会自动创建一个新任务 。
我们正在努力保留它 RESTful。告诉调用用户已创建新任务的正确方法是什么?我想到了以下解决方案,但我认为它们都有缺点:
- 在
PUT
响应中包含一个附加字段,其中包含有关最终新任务的信息。 - Return 仅更新任务,并期望用户调用
GET /tasks
以检查是否已创建任何新任务。
选项 1 在我看来打破了 RESTful-ness,因为 API 预计 return 仅关于更新实体的信息。选项 2 希望用户做一些事情,但如果他不做,那么没有人会意识到创建了一个新任务。
谢谢。
更新: PUT
在更新任务的完整 JSON 表示中调用 return HTTP 200 代码。
@tophallen 建议有一个任务树,这样(如果我做对了)选项 2 中的 returned 实体包含新任务作为直接子任务。
您确实有 2 个选项和 200 个状态 PUT,您可以执行 headers(如果您这样做,请查看 this post)。当然不是一个坏的选择,但你会想要确保它被规范化 site-wide,有据可查,并且你没有任何东西,例如 firewalls/F5's/etc/ re-writing 你的 headers.
虽然这样的事情是一个公平的选择:
HTTP/1.1 200 OK
Related-Tasks: /tasks/11;/tasks/12
{ ...task response... }
或者您必须在响应中向客户提供一些指示 body。您可以有一个支持 child 任务的任务结构,或者您可以规范化所有响应以包含 "meta" 东西的空间,即
HTTP/1.1 200 OK
{
"data": { ...the task },
"related_tasks": [],
"aggregate_status": "PartiallyComplete"
}
像这样的东西随处可见(有点工作,因为听起来你不只是开始这个项目)可能非常有用,因为你也可以将它用于分页等场景。
就我个人而言,我认为如果你让 related_tasks
属性 只包含调用 child 任务的路由,或者调用 id,那可能是最好的、更轻松的响应,因为客户可能并不总是关心立即打电话检查所说的 child-task。
编辑: 实际上,我考虑得越多 - 在您的情况下 header 越有意义 - 因为客户端可以在任务处理期间的任何时候更新任务,所以可能有也可能没有 child 任务在进行中 - 因此当 child 任务开始时修改 off-chance 客户端调用以更新任务的数据结构似乎工作多于好处。 header 将允许您轻松添加 child 任务并在 任何 点通知用户 - 您可以对 POST 应用相同的事情恰好立即完成并启动 child 任务等的任务。它可以轻松支持多个任务。我认为这也使它保持最多 restful 并减少了服务器调用,客户端将始终能够知道流程链中发生了什么。 header 的细节可以定义,但我相信在这种情况下更传统的做法是让它指向资源,而不是 within 资源的键。
如果还有其他选择,我很想听听。
看起来你很在意RESTful,但你没有使用HATEOAS,这是矛盾的。如果您使用 HATEOAS,则相关实体只是另一个 link,客户可以随意关注它们。您所拥有的在 REST 中没有问题。如果这对您来说听起来很陌生,请阅读以下内容:http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Option 1 breaks the RESTful-ness in my opinion, since the API is expected to return only information regarding the updated entity.
这不是真的。 API 预计 return 任何被记录为该媒体类型可用信息的内容。如果您记录了一个任务有一个用于相关副作用任务的字段,那么它没有任何问题。