当谈起 API 设计时,人们首先会想到 REST API,它是 Representational State Transfer 的缩写。REST API 是标准化的工具,它通过 URL 的方式从服务器上获取数据。
世纪交替之际,客户端应用程序还是相对简单的。那时,REST 已经开发出来了,并且适时地成为了许多客户端应用程序的绝佳选择。
这个 API 的提出在当时是革命性的,因为它提出了重要的 API 设计概念,比如无状态服务器和对资源的结构化访问。
随着 API 设计越来越复杂,并且越来越多地依赖数据驱动,API 设计的好坏需要看以下几个关键的评估点:
IBM,推特、沃尔玛实验室、纽约时报、Intuit、Coursera 是最先一批从 RESTful API 转移到 GraphQL API 上去的公司,它们希望仅在公司内部使用新的 API,这些公司宣称这次 API 的转型非常成功。
像 AWS、Yelp、GitHub、Facebook 和 Shopify 这样的公司则更进一步,因为它们将 RESTful 转移到 GraphQL API 上,不仅是为了在公司内部使用,而且还对外使用。
简单来说,GraphQL 是一个开源的查询语言和协议 API。你可以把 GraphQL 想象成 SQL,只是把数据库换成 API。
GraphQL API 是基于 REST 架构的现代化替代者。不同于 REST,GraphQL 允许客户端根据其需要请求特定的部分数据,这与请求固定数据结构的方式不同。
GraphQL 真的有什么实用价值吗,它会成为 API 领域的弄潮儿吗?
有趣的是,本文目前提到的这些公司都有如下共同点:
正如 GitHub 工程师们做出的正确解读:“在前端和后端使用 GraphQL 消除了我们发布的内容和你可以消费的内容之间的差距。我们真的很期待同时发布更多类似内容。
GraphQL 是 API 开发领域向前迈进的重要一步。类型安全、内省、文档生成和可预测响应对平台的维护者和平台的使用者都有好处。
“我们期待着我们基于 GraphQL 平台的新纪元,我们也希望你也是满怀着这样的期待!”
GraphQL 服务器会给客户端下发一套预定义的模式。这个基本上是可以从服务器上检索到的模型数据,而这个预定义的模式作为服务器和客户端之间的连接器,它定义了获取信息的过程。
GraphQL 模式的基本元素是用 SDL(Schema Definition Language:模式定义语言)写的,它阐明了所有能向那台特定服务器请求到的对象类型,包括这些对象要处理的各个字段。
客户端能向服务器请求到什么类型的数据,以及这些数据类型之间的关系等,这些查询都是由这个模式定义的。
实际上,GraphQL 模式是可以不断开发的,并且可以围绕这个模式采用任何编程语言来创建出接口。
为了确保服务器能够响应客户端发起的查询,客户端可以在本地根据这个预定义模式来验证其查询的正确性。你可以根据 GraphQL 的查询结构(这个结构和查询结果非常相似)来预测输出。
这样还能避免非预期的意外情况发生,例如结构不正确或者数据无法获取等。
当 GraphQL 操作到达后端应用时,后端将根据完整的模式进行解析。只有这样,前端应用程序的数据才能被完全准确地解析。
在 GraphQL 开发环境中,主要有 3 种操作。它们是:
开发者对 GraphQL 所采用的客户端驱动的方法非常感兴趣。这仅仅是因为 GraphQL 做了如下的改进:发出一次查询请求后,只用接收所需要的数据,而不是完整数据集。
在数据控制流被移交到客户端这边的 GraphQL 时,请求发出后,其返回的数据类型就已经确定了。
另一方面,REST 还遇到了“过度抓取数据”的问题。服务器为每项资源都定义了可用的数据。
即使只需要部分数据,客户端都不得不请求资源库中的整套信息,这需要反复进行网络请求。
GraphQL 和 REST 都是一种规范,是用来构建和使用 API 的规范。这两种技术常用的特性是,当它们通过发送请求来检索资源时,都能返回所请求的 JSON 数据。
另外,它们都能通过 HTTP 进行操作。此外,REST 和 GraphQL 字段的接入点或多或少都是类似的,因为它们都是作为数据调用服务器上函数的入口。
尽管它们有这么些共同点,但是它们的概念模型也有着很大不同。GraphQL 是基于图来创建的,而 REST 是基于文件而创建的。
说起性能,GraphQL 要快得多,因为你可以通过选择你感兴趣的查询字段来减少请求次数。
以下是使用了 GraphQL API(而非 REST API)之后所带来的一些较为明显的好处。
GraphQL 将多个系统集成到 API 中,从而形成了统一的 API 接口,并且能够将各个系统的复杂性隐藏在 API 背后。GraphQL 服务器的任务就是从当前这些系统中获取数据,并且将数据打包放入 GraphQL 返回的数据格式中。
许多第三方 API 和传统的基础设施在这些年经历了大举扩张,对于这样的 API 和基础设施,GraphQL 与多系统的匹配性尤其重要,因为匹配得不好就会带来维护负担。
如果系统从一个单一的后端迁移至微服务架构,把多个微服务融合进 GraphQL 模式能够帮助微服务间更好地通信。
即使每个微服务都定义了自己的 GraphQL 模式和自己的 GraphQL 接入点,多个微服务还是可以通过单一的 GraphQL API 网关整合到一个全局模式中。
如果使用 REST API,那么开发者需要把多个接入点合并起来才能收集到所有需要的数据,因为 REST 散落分布在多个独立的接入点上。
GraphQL 与 REST 的主要区别就在这里。开发者仅仅通过一个 API 调用就可以请求到所需信息,而 GraphQL 会专注于主体任务。
从 REST 收到的响应来看,有一个不稳定的因素,即收到的信息里要么信息不足,要么信息冗余,这样就不可避免地需要再发出一次请求。而 GraphQL 就解决了这个问题,因为它只需请求一次,就能够获取所需的精确的数据信息。
开发者按照 REST API 文档描述发出请求时,只能请求一些特定的接入点、相关函数和参数等。
而另一方面,GraphQL 可以描述数据类型、字段以及它们之间的任何交互连接点。这就允许 GraphQL 开发者自定义请求格式来获取必要的信息。
GraphQL 的自省特性能够为开发者导航到某个数据类型,找到相应的数据模式,确保 App 采用正确的结构发出有效的请求。
虽说 GraphQL 会检查已有模式的结构正确性,但是开发者想为当前查询添加新的字段也是可以的,开发者可以通过 GraphQL IDE 做到这点,他们不用去进一步验证数据格式的合法性,只需要开发者们为新数据结构编写解析器即可。
GraphQL 的文档和 API 修改是同步进行的,因为 GraphQL 文档和其代码联系紧密。于是,代码修改,哪怕是一个字段、一次查询或者是数据类型的修改,也会触发文档的自动更新。
REST 提供了好几个 API 版本,它的 API 在不断进化修改,这意味着开发者们如果不想只支持新版本的 API,那他们就得保留 API 的旧版本。
GraphQL 就省略了该步骤,开发者们不用保留 API 旧版本,因为老旧的字段可以从模式中移除,而不会在今后影响到以前已有的查询。
这就确保了开发者可以在 GraphQL 的进化版本中连续获取到 App 的新特性,服务端的代码也因此变得更加干净和容易维护。
如果有重用的需求,那么可以在更高的组件级别,对 GraphQL 多个查询中使用的字段进行共享。这些所谓的片段能够让你访问各种类型的数据,同时仍然遵守相同的模式字段。
要确定什么地方出了问题,以及需要做什么来应对问题时,在 REST 中只要检查 HTTP 头的响应状态就足够了。
但是,在 GraphQL 中,如果在处理数据时报错了,后端会提供一条详细的信息,因为后端带有解析器。这些信息会提供查询中错误所在的精确位置。
在创建 GraphQL 模式时,可以选择展示哪些函数和操作。和 REST 视图功能相比,这不是好不好的问题,而是有无的差别。
所以这里的想法是,各个视图应当知道在特定场景中哪些东西是需要显示的,哪些是不用显示的。这可不是什么轻而易举就能做到的事情。
我们不能说 GraphQL 是要完全取代 REST,因为前者只是一个工具,而 REST 是一种架构模式。具体哪一个更合适,将取决于它们独特的交互场景。
领取专属 10元无门槛券
私享最新 技术干货