是否有标准方法可以将多个 API 调用组合成一个 HTTP 请求?

2023-12-25

在设计 REST API 时,我有时会遇到处理批量操作(例如一次删除或更新许多实体)以减少许多 tcp 客户端连接的开销的挑战。在特定情况下,问题通常通过添加特定操作的自定义 api 方法来解决(例如POST /files/batchDelete它接受ids从 REST API 设计原则的角度来看,这看起来不太漂亮,但可以完成工作。

但对我来说,问题的通用解决方案仍然是可取的。最近我发现Google Cloud Storage JSON API 批处理文档 https://cloud.google.com/storage/docs/json_api/v1/how-tos/batch?hl=en对我来说这看起来是非常通用的解决方案。我的意思是类似的格式可以用于任何 http api,而不仅仅是谷歌云存储。所以我的问题是 -有人知道将多个 API 调用合并到一个 HTTP 请求中的通用标准(标准或其草案、指南、社区工作等)吗?

我知道 http/2 的功能,其中包括使用单个 tcp 连接进行 http 请求,但我的问题是针对应用程序级别的。在我看来,这仍然有意义,因为尽管能够使用 http/2,但在应用程序级别上使用 http/2 似乎是保证任何客户端(包括当前最常用的 http 版本 http/1)的唯一方法。


TL;DR

  • REST 和 HTTP 都适合批量操作。
  • 通常,缓存是 REST 约束之一,不是可选的而是强制的,它会阻止某种形式的批处理。
  • 不将要批量更新或删除的数据公开为自己的资源,而是将其公开为单个资源中的数据元素(如 HTML 页面中的数据表),这可能是有益的。这里更新或删除全部或部分条目应该是直接的。
  • 如果系统总体上是写入密集型的,那么最好考虑其他解决方案,例如将数据库直接暴露给这些客户端,以节省进一步的间接性和复杂性。
  • 利用缓存可以避免服务器上的大量工作负载,甚至可以节省不必要的连接

首先,REST 和 HTTP 都适合批量操作。正如吉姆·韦伯指出的。这就是 HTTP 所做的事情,也是它所擅长的。然而,我们得出的任何业务规则都只是文档管理的副作用,我们必须提出解决方案,将这种文档管理副作用转化为有用的东西。

由于 REST 只是可浏览 Web 中使用的概念的概括,因此适用于 Web 开发的相同概念也以某种形式适用于 REST 开发也就不足为奇了。因此,诸如应该如何在 REST 中完成某些操作的问题通常会围绕回答如何在 Web 上完成某些操作来解决。

如前所述,HTTP 在批处理操作方面并不理想。当然,一个 GET 请求可能会检索多个结果,但实际上您会获得一个包含指向更多资源的链接的响应。根据《资源的创造》HTTP规范 https://www.rfc-editor.org/rfc/rfc7231#section-4.3.3,用a表示Location指向新创建的资源的标头。POST被定义为一种通用方法,允许根据服务器特定的语义执行任务。所以你基本上可以用它来一次创建多个资源。然而,HTTP 规范显然缺乏对指示同时创建多个资源的支持Locationheader 对于每个响应只能出现一次,并且在其中只能定义一个 URI。那么服务器如何向服务器指示多个资源的创建呢?

HTTP 不适用于批处理的进一步迹象是 URI 必须引用单个资源。尽管 URI 不可能同时指向多个资源,但该资源可能会随着时间而改变。 URI 本身或多或少被缓存用作密钥,缓存存储该 URI 的可缓存响应表示形式。由于 URI 可能仅引用一个资源,因此缓存也仅存储该 URI 的一个资源的表示形式。如果对 URI 执行不安全的操作,缓存将使存储的 URI 表示无效。如果出现DELETE操作,本质上是不安全的,URI 的表示DELETE执行后将被删除。如果您现在“重定向”DELETE一次删除多个后备资源的操作,缓存应该如何注意这一点?它仅对调用的 URI 进行操作。因此,即使您一次性删除多个资源DELETE缓存可能仍然为客户端提供过时的信息,因为它根本没有注意到删除,并且它的新鲜度值仍然表明足够新鲜的状态。除非您默认禁用缓存,这在某种程度上违反了其中之一REST 的限制 https://restfulapi.net/rest-architectural-constraints/#cacheable,或者将表示被认为足够新鲜的时间段减少到非常低的值,客户可能会得到过时的信息。当然,您可以对每个 URI 执行不安全的操作,然后“清除”缓存,尽管在这种情况下您可以调用DELETE对您想要批量删除自身的每个资源进行操作。

不过,如果您要删除的一批数据不是通过其自己的资源显式捕获而是作为单个资源的数据捕获,那么它会变得更容易一些。想象一下网页上的数据表,其中有某些表单元素,例如您可以单击复选框将条目标记为删除候选者,然后在调用提交按钮后将相应的选定元素发送到执行操作的服务器删除这些项目。这里仅更新一个资源的状态,因此一个简单的POST, PUT甚至PATCH可以对该资源 URI 执行操作。这也很适合前面概述的缓存,因为只需更改一个资源,通过在该 URI 上使用不安全的操作将自动导致给定 URI 的任何存储表示形式失效。

然而,上述使用表单元素来标记某些要删除的元素取决于所发布的媒体类型。对于 HTML 来说,它的表格部分 https://www.w3.org/TR/html52/sec-forms.html指定可用的组件及其。可供性是指你可以并且应该对某些对象做什么的知识。 IE。按钮或链接可能需要被按下,文本字段可能需要数字或字母数字输入,其进一步可能受到长度限制等等。其他媒体类型,例如哈尔形式 https://rwcbook.github.io/hal-forms/, halform http://halform.herokuapp.com/ or ion https://ionspec.org/#forms,尝试为基于 JSON 的表示法提供表单表示和组件,但是,对此类媒体类型的支持仍然相当有限。

由于您关心的问题之一是与服务的客户端连接数量,我假设您有一个写入密集型场景,因为在读取密集型情况下,缓存可能会带走服务器的很大一部分负载。 IE。 BBC 曾报道称,他们只需为最近请求的资源引入一分钟的缓存间隔即可大幅减少服务器上的负载。这主要影响了他们的起始页和链接文章,因为人们点击最新新闻的频率高于旧新闻。如前所述,每分钟收到数千甚至数十万个请求时,他们可以显着减少实际到达服务器的请求数量,从而减轻服务器上的巨大负载。

然而,写入密集型用例无法像读取密集型用例那样充分利用缓存,因为缓存经常会失效,并且实际请求会转发到服务器进行处理。如果 API 或多或少用于执行 CRUD 操作(正如现实中许多“REST”API 所做的那样),那么将数据库直接暴露给客户端是否更好是值得怀疑的。几乎所有现代数据库供应商都提供了复杂的用户权限管理选项,并允许创建可以向某些用户公开的视图。在这种情况下,其之上的“REST API”基本上只是增加了进一步的间接性和复杂性。通过直接公开数据库,执行批量更新或删除根本不应该成为问题,因为通过相应的查询语言对此类操作的支持应该已经构建到数据库层中。

关于客户端创建的连接数量: HTTP 从 1.0 开始允许通过以下方式重用连接:Connection: keep-alive https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection标头指令。在 HTTP/1.1 中,如果没有通过相应的显式请求关闭,则默认使用持久连接。Connection: close标头指令。 HTTP/2 引入了全双工连接,允许多个通道,因此请求可以同时重用相同的连接。这或多或少是对中建议的连接限制的修复RFC 2626 https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4许多 Web 开发人员通过使用 CDN 和类似的东西来避免这种情况。目前,大多数实现使用 100 个通道的最大限制,因此据我所知,可以通过单个连接同时下载。

通常打开和关闭连接需要一些时间和服务器资源,服务器必须处理的打开连接越多,系统可能遭受的损失就越大。尽管几乎没有任何流量的开放连接对于大多数服务器来说并不是一个大问题。虽然连接创建通常被认为是成本高昂的部分,但通过使用持久连接,该因素现在转向了发出的请求数量,因此需要发送批量请求,而 HTTP 并不是真正为之而设计的。同样,正如整篇文章中提到的,如果可能的话,通过巧妙地利用缓存,大量请求可能永远不会到达服务器。这可能是减少同时请求数量的最佳优化策略之一,因为大量请求可能根本不会到达服务器。在这种情况下,最好的建议可能是查看哪些类型的资源被频繁请求,哪些请求占用了大量的处理能力,以及哪些请求可以通过利用缓存选项轻松得到响应。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否有标准方法可以将多个 API 调用组合成一个 HTTP 请求? 的相关文章

  • Rest 和 Http 中“无状态”的含义

    当我阅读有关 REST 是什么的文档时 他们总是说 REST api 应该是无状态的 在这里 我感觉有点尴尬 因为普通的 HTTP 也是无状态的 既然REST可以说是一种使用HTTP协议的特殊架构 那么说REST应该是无状态的似乎是多余的
  • React + Redux 和 REST API?

    我在 Node 中构建了一个简单的 CRUD 应用程序 并已在 Express 中完成了其余 API 的创建 我现在正在寻求添加前端功能 并希望使用 React Redux 作为学习练习 然而 似乎所有围绕此的教程都直接使用 Redux 访
  • Django Rest Framework 完整性错误捕获

    在 Django Rest Framework 中 我使用了序列化器 视图集和路由器方法 每当我在 django Rest 框架的 API 视图中发布故意错误时 它都会抛出完整性错误 有没有办法尝试捕获错误 例如如果数据中没有错误 则继续保
  • 如何在 G-WAN 中添加 HTTP/2

    我想知道是否可以通过使用解决方案 nghttp2 https nghttp2 org https nghttp2 org 很抱歉这么晚才回答 出于某种原因 Stackoverflow 没有通知我们这个问题 我之所以找到它只是因为收到了更新的
  • AngularJS 1.X 中的异步调用是如何工作的? $Http 调用没有返回值

    我有以下名为的函数getvalue 它与控制器一起位于 AngularJS 模块内 我试图在单击事件上调用此函数 调用控制器中的另一个函数 我希望我很清楚 功能 function getvalue Data http var value u
  • 使用 POST 请求向 Jira API 发送 JSON 时出现 System.Net.WebException

    好吧 伙计们 我已经为这个问题苦苦挣扎了一天左右 但没有明确的解决方案 我将从例外开始 The remote server returned an error NotFound at System Net Browser AsyncHelp
  • Response.Redirect 并不总是重定向

    我们在一个工作不一致的页面上有一个简单的 Response Redirect IIS 6 0 大多数情况下 它会正确重定向 但我们收到一些用户抱怨 他们没有重定向 而是看到 302 对象移至此处 页面 该页面显示标题信息以及正确的位置 如果
  • 传递自定义类型查询参数

    如何接受自定义类型查询参数 public String detail QueryParam request final MYRequest request 上面的行在启动服务器时出现错误 jersey server model ModelV
  • 为休息服务实施 JUnit 测试

    我必须为我的休息服务实现一些 JUnit 测试 例如 这是我的休息服务之一 Path dni fe public class HelloWorld POST Path home Consumes MediaType APPLICATION
  • struts2-rest 插件..使 struts 操作 + 休息操作一起工作,但是。给出 java.lang.reflect.InitationTargetException

    我正在将现有的 struts 2 应用程序转换为通过一些基于休息的服务来提供服务 我使用了两个插件 struts2 rest插件和struts convention插件 除了这些之外 我还使用了 asm jar 因为上面给出了 asm ja
  • 泽西岛的全局异常处理

    有没有办法在泽西岛进行全局异常处理 我希望有一种方法可以将其放置在实际调用资源的位置 而不是让单个资源具有 try catch 块 然后调用某种方法来清理所有要发送回客户端的异常 这可能吗 如果是这样 怎么办 而不是 在哪里sanitize
  • 使用 Swagger 的 Spring REST API 文档 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个可以帮助我生成 RESTful API 文档的工具 我的服务器是用Java编写的并使用S
  • RESTful API:我应该在哪里编码我的工作流程?

    我正在开发一个 RESTful API 这是我的第一个 API 也是我的第一个真正大型的编码项目 因此 我仍在学习很多关于建筑等方面的知识 目前 我的 api 设置分为以下几层 HTTP层 资源层 领域模型 业务逻辑层 数据访问 存储层 持
  • 为什么我在 Firefox 中突然遇到“阻止加载混合活动内容”问题?

    今天早上 在将我的 Firefox 浏览器升级到最新版本 从 22 到 23 后 我的后台 网站 的一些关键功能停止工作 查看Firebug日志 报告了以下错误 Blocked loading mixed active content ht
  • 实体创建无用的 id 字段

    我有一个CrudRepository与两个实体 Problem 特征实体总是创建一个附加的id数据库中的字段但未选择正确的characteristic id要生成的字段JSON machine entity machine id name
  • 如何让 HttpClient 返回状态码和响应正文?

    我试图让 Apache HttpClient 触发 HTTP 请求 然后显示 HTTP 响应代码 200 404 500 等 以及 HTTP 响应正文 文本字符串 重要的是要注意我正在使用v4 2 2因为大多数 HttpClient 示例都
  • Node.js 上的 Connect 出现“无法 GET /”

    我正在尝试使用以下方式开始提供一些静态网页connect像这样 var connect require connect var nowjs require now var io require socket io var app conne
  • 当分配返回 0 时,具有空异常规范的运算符 new 调用构造函数

    我有以下声明 void operator new size t s PersistentMemory m throw return m gt allocatePersistentMemory s 我正在测试启动时的内存耗尽 这会导致m gt
  • Java 中的下载管理器 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要通过 FTP HTTP 从 Java 获取几个大文件 几个演出 有现成的库 java 命令行工具
  • 不同 servlet-api 版本冲突

    我正在使用 Maven 和 Jetty 作为服务器来开发 RestEasy Web 服务 其中一项服务应使用扩展 javax servlet http HttpServletResponseWrapper 的 Filter 问题出在来自 s

随机推荐