REST API 200 和 201 正文响应

API*_*lex 6 api rest standards

问题\n我正在为我的公司编写 API 标准文档,并且一直在尝试各种工具来增强我们的 API 生命周期,今天我尝试了 apisecurity.io 的 API 定义安全验证工具,\ nit 突出显示了一个有趣的错误:我的 POST 操作:\n\xe2\x80\x9c您尚未为应包含正文的响应定义任何架构。\xe2\x80\x9d 链接:响应架构未定义并引用 RFC 7231

\n

标记的 API 端点是一个 POST 操作,该操作返回: 201 状态代码、 Location header 但没有 body。(因此会出现错误,因为该工具期望除 204 之外的所有 200 代码都有主体)

\n
\n

研究\ nRFC7231 第 6.3.2 节指出:

\n
\n

201(已创建)状态代码表示请求已\n得到满足,并导致\n创建一个或多个新资源。请求创建的主要资源由响应中的位置标头字段标识,或者如果未接收到位置字段,则由有效请求 URI 标识。

\n
\n
\n

201 响应负载通常描述并链接到所创建的资源。请参阅第 7.2 节,了解 201 响应中验证器标头字段(例如 ETag 和 Last-Modified)的含义和用途的讨论。

\n
\n

另外,当查看RFC7231 第 4.3.3 节为 POST 操作定义的内容时(当操作导致创建资源时),它指出:

\n
\n

如果作为成功处理 POST 请求的结果,在源服务器上创建了一个或多个资源,\n源服务器\n应该发送包含 Location 标头\n字段的 201(已创建)响应,该字段为创建的主要资源提供标识符\n(第 7.1.2 节)以及在引用新资源时描述\n请求状态的表示。”

\n
\n
\n

解释\n当 POST 导致资源创建成功时:

\n
    \n
  • 应返回 HTTP 201
  • \n
  • Location 标头应与新创建资源的 URL 一起返回
  • \n
  • “在引用新资源时描述请求状态的表示”
  • \n
\n

前两项并不令人意外,但第三项是我发现标准要求和可作为先例的指导相互矛盾的地方。\n根据我的研究,Google、Paypal、Github 和 Stripe,所有信誉良好的 API 创建者,发送新创建资源的完整表示,而不是“请求状态的表示”。

\n

RFC 是否错误/过时,最佳实践是我们应该返回完整正文吗?\n我非常重视遇到/争论过此问题或对对话感兴趣的其他人的意见。

\n

这似乎是一个微不足道的问题,但我正在尝试记录推动一致性的最佳实践,类似于Zalendo(似乎也返回资源,除非返回 204,但在这种情况下,客户端不知道资源是否已创建,或者是否它已由 POST 更新)

\n

要回答的问题\n这种类型的响应主体是否有可遵循的标准?

\n

同样的答案也适用于获得 200 响应的 PUT 或 POST 或获得 201 响应的 PUT。

\n

Voi*_*son 8

RFC 是否错误/过时,最佳实践是我们应该返回完整正文?我真的很重视遇到过/争论过这个问题或对对话感兴趣的其他人的意见

据我所知,RFC 很好。

我认为您缺少的想法是Content-Location,也就是说我们可以在响应中使用元数据以标准化的方式明确我们从服务器发回的表示是什么。

典型的“动作状态的表示”可能看起来像

201 Created
Location: /api/new-things/12345

Your document can be fetched from /api/new-things/12345
Run Code Online (Sandbox Code Playgroud)

相反,如果我们想发送我们创建的新文档(资源)的表示,那么我们需要在元数据中发出信号。

201 Created
Location: /api/new-things/12345
Content-Location: /api/new-things/12345

Hi, I'm your new document, which can be fetched from /api/new-things/12345
Run Code Online (Sandbox Code Playgroud)

粗略地说 - 是的,您可以只发送您在服务器上创建的新事物的表示,并且您的定制客户端可以理解这一点。但我们有一个问题,通用组件也需要理解对话,就他们而言,我们正在讨论 target-uri,而不是/api/new-things/12345.

HTTP 标准是使用所有资源和组件通用的语义来描述正在发生的事情,而不是与特定 URI 对话的特定 Java 脚本。