GraphQL vs REST API 架构

Posted by huangqing on January 28, 2021

概述

API 在客户端 - 服务器结构中的作用:API(应用程序编程接口)是一个中间层,它允许服务器从客户端接收结构化数据请求,并针对请求的数据发送结构化的响应。

GraphQL 是一个开源的查询语言和协议 API。可以把 GraphQL 想象成 SQL,只是把数据库换成 API。

使用GraphQL的公司的特点:

  • 它们都有几个移动客户端;
  • 它们都计划转到微服务架构上,或者已经在使用微服务架构了;
  • 它们对 RESTful API 的依赖成倍增加,这种依赖性变得更加复杂了;
  • 它们正在寻找方法移除对它们客户端团队的依赖,而转向依赖 API 团队;
  • 它们看重开发者的经验,并且重视优秀的 API 文档。

REST

REST 也许是最通用,也是最常用的接口设计方案,它是 无状态的,以资源为核心,针对如何操作资源定义了一系列 URL 约定,而操作类型通过 GET POST PUT DELETE 等 HTTP Methods 表示。

gRPC

gRPC 是对 RPC 的一个新尝试,最大特点是使用 protobufs 语言格式化数据。

RPC 主要用来做服务器之间的方法调用,影响其性能最重要因素就是 序列化/反序列化 效率。RPC 的目的是打造一个高效率、低消耗的服务调用方式,因此比较适合 IOT 等对资源、带宽、性能敏感的场景。而 gRPC 利用 protobufs 进一步提高了序列化速度,降低了数据包大小。

GraphQL

GraphQL 不是 REST 的替代品,而是另一种交互形式:前端决定后端的返回结果。

GraphQL 带来的最大好处是精简请求响应内容,不会出现冗余字段,前端可以决定后端返回什么数据

相比 REST 和 gRPC,GraphQL 是由前端决定返回结果的反模式。

Webhooks

如果说 GraphQL 颠覆了前后端交互模式,那 Webhooks 可以说是彻头彻尾的反模式了,因为其定义就是,前端不主动发送请求,完全由后端推送。

它最适合解决轮询问题。

适用的场景

  • REST:无状态的数据传输结构,适用于通用、快速迭代和标准化语义的场景。
  • gRPC:轻量的传输方式,特殊适合对性能高要求或者环境苛刻的场景,比如 IOT。
  • GraphQL: 请求者可以自定义返回格式,某些程度上可以减少前后端联调成本。
  • Webhooks: 推送服务,主要用于服务器主动更新客户端资源的场景。

GraphQL 服务器的设计原则

GraphQL

  1. 查询为分层结构 ,使用将查询与响应数据1对1匹配的分层和嵌套字段格式。
  2. 该结构以产品为中心,关注前端希望如何接收数据,并构建交付所需的运行时 。
  3. 它使用特定于应用程序的类型系统 ,该系统使开发人员能在执行前确保查询使用了有效类型,并且语法正确。
  4. GraphQL 查询是在客户端指定的,因此,客户端确切知道它将以何种格式接收数据 。
  5. 使用 GraphQL 的服务器结构必须是内省的 ,或者可由 GraphQL 自己查询。

传统的 RESTful 架构

REST 架构的设计范式侧重于分配 HTTP 请求方法(GET、POST、PUT、PATCH、DELETE)和 URL 端点之间的关系。

RESTful-API

在 REST 架构中,方法和端点的每个组合得到不同的封装功能。从 REST 请求返回的数据格式依赖于端点—不能保证这些数据会按照前端需要的方式进行格式化。为使用来自响应的数据(格式与缺省情况下从端点返回的格式不同),必须在客户端编写数据解析和数据操作。

GraphQL 架构

GraphQL API 设计用于处理 HTTP 请求并对这些请求提供响应。。REST API 构建在请求方法和端点之间的连接上,而 GraphQL API 被设计为只通过一个端点,始终使用 POST 请求进行查询,其 URL 通常是 yourdomain.com/graphql

graphql-API

请求到达 GraphQL 端点后,客户端请求的载荷完全在请求体中处理。这个请求体必须遵循 GraphQL 规范,API 必须有适当的服务器端逻辑来处理这些请求并提供适当的响应。

这提供了比 RESTful API 更流畅的客户端体验,后者可能要求客户端针对多个数据块发出多个请求,并在数据返回后进行操作。

GraphQL VS REST

从技术来看,REST API通过调用POST、GET、DELETE、PUT等方法去执行多个API操作,通常从多个端点进行加载数据,但GraphQL API可以通过单个POST请求中获得应用所需的所有数据。

REST API 的接口灵活性差、接口操作流程繁琐,GraphQL 的声明式数据获取,使得接口数据精确返回,数据查询流程简洁,照顾了客户端的灵活性。

客户端拓展功能时要不断编写新接口(依赖于服务端),GraphQL 中一个服务仅暴露一个 GraphQL 层,消除了服务器对数据格式的硬性规定,客户端按需请求数据,可进行单独维护和改进。

REST API 基于HTTP协议,不能灵活选择网络协议,而传输层无关、数据库技术无关使得 GraphQL 有更加灵活的技术栈选择,能够实现在网络协议层面优化应用。

GraphQl开源生态圈

服务端实现

在服务端, GraphQL 服务器可用任何可构建 Web 服务器的语言实现。有以下语言的实现供参考:

C# / .NET、Clojure、Elixir、Erlang、Go、Groovy、Java、JavaScript、Julia、Kotlin、Perl、PHP、Python、R、Ruby、Rust、Scala、Swift… 种类繁多,几乎流行的语言都有支持。

客户端实现

在客户端,Graphql Client目前有下面的语言支持:C# / .NET、Clojurescript、Elm、Flutter、Go、Java / Android、JavaScript、Julia、Swift / Objective-C、iOS、Python、R。覆盖了众多客户端设计语言,而其他语言的支持也在推进中。