首页 > 解决方案 > 类似于 REST 但也使用像 GraphQL 这样的突变的 API?

问题描述

设计一个类似于 REST 的 API 是否会有任何巨大的缺陷,因为资源有 GET 端点(即 /courses、/professors、/students),但所有 POST/PUT/DELETE 都使用单个端点(即 /动作)带有指定如何处理请求以及处理请求所需的必要信息的有效负载(即 { action_name = "create_course", name = "math" } 或 { action_name = "drop_course", course_id = 5 }) .

标签: restapigraphqlrpc

解决方案


会不会有很大的缺陷

缓存。

缓存是REST 架构风格中的一个重要元素;“大粒度超媒体数据”希望被缓存,这样您就不会通过网络反复发送相同的数据。在 HTTP 中,我们有一个专门用于缓存语义的 RFC 。这包括缓存失效——如果有一个成功的不安全请求,通用的 http 感知组件将知道使缓存条目失效。

因此,通过将所有不安全的请求路由到单个端点,通用组件最终会将缓存失效应用到操作端点,而不是应用到请求实际更改的任何资源。

DELETE有一个额外的缺陷——它不需要有效载荷

DELETE 请求消息中的有效负载没有定义的语义;在 DELETE 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。

因此,任何参与消息交换的通用组件都将假定/actions端点已被删除,而不是负载引用的任意资源。

PUT有一些不同的问题

PUT 方法请求创建目标资源的状态或将其替换为请求消息有效负载中包含的表示定义的状态。

因此,在您的情况下,通用组件将假设您的消息实际上是/actions资源的提议表示。

统一接口的要点是每个人都同意语义,并且您可以从不了解您的特定域的通用 HTTP 感知库中提取价值。当您开始在语义上犯错时,您将对可能发生的任何财产损失承担责任。

远程创作语义(PUT/PATCH/DELETE)确实不适合单个/actions端点。

POST 做得更好一些,因为约束是最小的。在某种程度上,将所有内容发布到单个端点将 HTTP 从应用程序协议减少到传输协议。

请注意,GraphQL 和之前的 SOAP 接受了这种权衡。课程用马。

什么是“通用 HTTP 组件”?

浏览器、缓存、代理、服务器、爬虫......任何可以访问正在交换的消息的东西,但不能访问您域的带外细节。

另外,成功的不安全请求的缓存失效是否意味着如果跟踪食谱,对 /recipes 的 GET 将被缓存,直到对 /recipes 的 GET/PUT/PATCH/DELETE 请求出现?

对 GET 的响应/recipes可能会被缓存,直到 POST/PUT/PATCH/DELETE/recipes出现。

它是否被缓存取决于响应提供的缓存标头的语义。

当然,我的本地缓存不会知道提出的请求,所以我可能正在查看过时的副本。不过,我会为自己的更改获得“阅读您自己的文章”语义。

更有趣的情况是服务器前面的反向代理,它会在成功的不安全请求后使其缓存条目无效,从而在仍然提供新数据的同时减少服务器的负载。


推荐阅读