我开发了一个 REST API。我想通过 API 本身提供请求参数。
这个想法的起源是aws cli 的“--generate-cli-skeleton”。
您是否知道有关为 REST API 端点返回请求参数的方式的任何名称或示例?
例如,添加特殊的请求标头以显示需要这样的骨架。
curl -X POST -H "Generate-Skeleton: True" https://exmaple.com/users
→{name: "", age: ""}
我开发了一个 REST API。我想通过 API 本身提供请求参数。
这个想法的起源是aws cli 的“--generate-cli-skeleton”。
您是否知道有关为 REST API 端点返回请求参数的方式的任何名称或示例?
例如,添加特殊的请求标头以显示需要这样的骨架。
curl -X POST -H "Generate-Skeleton: True" https://exmaple.com/users
→{name: "", age: ""}
我脑子里的基本问题仍然存在:你为什么需要它?
在我看来,就 REST 而言,这听起来像是一种反模式。REST 是针对机器而非人类的可浏览 Web 的概括,尽管适用于 Web 的相同概念基本上也适用于遵循 REST 架构的应用程序。
大量的 CRUD 服务允许通过POST请求创建新资源。这里有效载荷的语义由服务器定义。客户端要么需要有关如何创建此类有效负载的带外信息,要么服务器需要以某种方式教客户端此类信息。在 Web 上,这是通过表单完成的。表单不仅定义了所需的数据输入,还定义了将有效负载发送到的位置。在遵循 REST 架构风格的应用程序中也可以这样做。这里应该将表单描述为服务器和客户端都使用和理解的自己的媒体类型,类似于服务器和浏览器知道和理解的 HTML。在没有表示可以在 REST 架构中使用的表单的专用媒体类型的情况下,可以简单地重用 HTML 的表单功能,即
从服务器检索数据还应避免将资源解释为特定类型。这很容易使您陷入类型资源陷阱。相反content-type negotiation,应该在客户端通知服务器其功能并且服务器尝试以客户端可以使用的表示进行响应的情况下使用。关于上面提到的表单示例,客户端和服务器可以就某种application/form+json表示达成一致,其中服务器基本上返回与 HTML 表单相似的信息,只是在 JSON 语法中。但是,应注意自定义媒体类型。它们应该尽可能通用以适用于大量客户端,否则对此类媒体类型的支持将非常有限的可能性很高。
与 HATEOAS 一起,它基本上添加了对链接关系名称的支持并避免解析和解释 URI,但仅使用它们来调用目标端点上的下一个操作,这些是 IMO REST 架构强加于客户端和服务器的基本先决条件为了获得高度的解耦,服务器端可以自由进化,而不必担心破坏客户端并使客户端对变化更加健壮。
在应用这些步骤后,资源变得几乎可以自我描述。如果操作正确,则不需要外部文档或其他带外信息,也不需要基于客户端的存根/骨架类与 API 交互,因为最终 URI 和 HTTP 是客户端需要支持的必要接口。
如果您需要支持自定义标头,则服务器需要在没有这些标头的情况下通知客户端它会扩展它们。这类似于即基本身份验证。客户端向服务器发送请求,服务器以401 Unauthorized包含标头的响应进行响应,例如该标头WWW-Authenticate: Basic realm="fooBar"通知客户端服务器正在使用提及领域进行基本身份验证。许多客户端实现都知道用户和密码/密钥需要以类似的形式username:password进一步需要进行 base64 编码并附加到Basic字符串。这通常是在后面完成的,没有太多的输入。但是,对于自定义标头,这可能并不容易自动化。但是您仍然可以发出适当的错误代码,例如409 Conflict或422 Unprocessable Entity通知客户所需但缺少的标头。这样的自定义标头最好在媒体类型中进行描述,因为它们包括对交换的表示的句法和语义描述,包括可选标头。
如果您需要生成此类属性以生成客户端存根代码或配置,您几乎可能没有 REST,而是更多类似 RPC 的系统,该系统专为与您的 API 交互而定制,但在任何其他端点上都会失败. 这样的客户端代码可能,取决于它的内部结构,很容易破坏,但如果你改变你的 URI 结构或交换的消息格式中的某些东西。这也非常类似于 SOAP/WSDL 客户端存根代码生成,其中可以检索服务的 WSDL XML 表示,生成一些存根类,然后针对这些接口实现。这里的问题通常是,如果在生成客户端存根代码之后在 WSDL 文件中修改了某些内容,客户端需要重新生成存根类并最终更新其客户端代码以与创建的接口进行交互。如果您获得更新信息的唯一渠道是您不经常访问的渠道(即维护者主页),这尤其麻烦。在大多数情况下,您仅在服务已经更新时才会看到问题。这在几年前发生在我们身上几次,这迫使我们向部署在各种客户端机器上的应用程序推出一些更新,这使我们花费了几个人日来更新这些。
我希望你能明白为什么我认为这是 REST 方面的反模式,在这种模式下,服务器应该通知客户端采取进一步行动所需的所有东西,或者为客户端提供一种方法来提供缺失的信息并将其发送到服务器。
您是否考虑过使用类似 json-schema 的东西?
如果您确实需要某种 JSON 模板来处理请求,它们不应该存在于由资源访问的同一个 uri 上。
相反,您应该在 API 中创建一个单独的部分,例如:
GET /templates/user <- to fetch a 'skeleton' as you call it
要发现这些模板,您可以从现有 API 中的战术位置创建链接。这可能是Link:指向相关模板的某个标题。