我应该在具有多个步骤的 REST API 上使用啥响应代码?
Posted
技术标签:
【中文标题】我应该在具有多个步骤的 REST API 上使用啥响应代码?【英文标题】:What response code should I use on a REST API with multiple steps?我应该在具有多个步骤的 REST API 上使用什么响应代码? 【发布时间】:2018-10-20 20:21:48 【问题描述】:我正在开发一个需要多个步骤/验证来创建资源的 REST API,然后创建 POST /transfer
可能不会创建实际的传输资源(因为它需要额外的步骤),但不会因为它失败将触发第二步/验证。
在this answer 中,响应是一个不完整或挂起的事务,带有一个 id,资源包括用于完成事务的端点,如 /transaction/123/commit
或在我的情况下为 /transaction/123/verification/432
,客户端可以继续、中止或完成事务处理。
但是这些端点上可能的响应代码是什么? /transaction/123/commit
是否真的返回 201 是因为它创建了事务,还是在达到 pending
状态时创建了事务?
【问题讨论】:
您不能预先要求所有信息吗?第一个 POST 是否可以创建一个“请求”文档并返回“请求”ID,然后第二个调用可以开始处理请求? 不,我不能预先询问所有信息,因为某些验证是由第一个请求中的数据生成的挑战。 我想过隐藏其他资源,并考虑过它可以使用哪个名称,但我认为添加request
资源在这里没有帮助。可能是transaction_draft
之类的东西?
HTTP 和 REST 都不支持多步骤资源创建过程 OOTB。您可以创建类似于 GIT 提交的中间资源,这些资源描述了事务视图并允许稍后回滚,或者您拥有一个独特的资源,稍后您可以使用客户端发送的新信息更新(补丁/放置)。如果客户端对当前状态感兴趣,则返回 200 OK 和当前正文,否则为初始资源返回 201 Created 并为剩余部分返回 202 Accepted。进一步注意,REST 只关心资源的状态,而不关心事务。
【参考方案1】:
201(已创建)
状态码201 (Created) 表示创建(至少一个)新的HTTP 资源。创建资源的 URL 在响应的 Location
标头中发送。
如果POST /transfer
创建了资源/transaction/123/commit
——也就是说,如果对/transaction/123/commit
的请求现在可能会成功,而之前你有404(未找到)——那么用201 响应POST /transfer
是正确的和Location: /transaction/123/commit
。
如果POST /transfer
创建了多个资源,那么Location
必须是“主要”资源(在某种意义上)。
如果POST /transaction/123/commit
没有创建任何新资源,则响应 201 是不正确的,即使它确实创建了其他内容(如内部数据库记录)。
如果你无法想出一个 URL 来发送 Location
,这可能意味着你没有创建任何新资源,在这种情况下 201 是不正确的。
注意:Location
始终与请求 URL 相关,而不是与“API 根”或您可能拥有的任何此类概念相关。例如,如果POST /api/v1/foo/bar
创建/api/v1/foo/bar/baz
,则Location
的正确值将包括bar/baz
和/api/v1/foo/bar/baz
,但不包括/foo/bar/baz
。
200(正常)
状态码200 (OK) 表示一般成功。它可用于大多数成功的响应。这是一种安全的后备方式:它不会说太多,因此保证不会说太多错误并让客户感到困惑。
如果POST /transaction/123/commit
没有创建新资源就成功了,那么回复200是正确的。
204(无内容)
除了对GET
/HEAD
的响应外,状态码204 (No Content) 与 200 基本相同。如果您使用 204 表示与 200 不同的内容,则可能是在编造一个本地约定 — 与编造你自己的状态码 275。
其他
IANA 维护一个registry of standardized status codes。您可以在那里查找标准化的状态代码,以准确表达您想要表达的意思。
您通常不想使用非标准状态码,或错误地使用标准状态码,因为这会排除uniform interface,这是重点REST。
如果您发现自己一直在努力维护统一的接口,那么您可能根本不需要 REST,而应该使用 RPC。
【讨论】:
以上是关于我应该在具有多个步骤的 REST API 上使用啥响应代码?的主要内容,如果未能解决你的问题,请参考以下文章
在带有 HTTP 状态代码 405 的 REST API 中返回啥错误消息?