速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

GraphQL vs REST API 架构,谁更胜一筹?

  • 2020-01-18
  • 本文字数:2890 字

    阅读完需:约 9 分钟

GraphQL vs REST API 架构,谁更胜一筹?

2015 年,Facebook 开源 GraphQL。此后,它在前端 Web 中大受欢迎。传统的 REST API 有何不足?GraphQL 优势何在?在本文中,我们将深入探讨 GraphQL 的设计原则,比较 GraphQL 与 REST 的异同,并讨论 GraphQL 相对其他架构的优点。

一、你的 API 应该用哪项技术?

自从 2015 年 Facebook 开源 GraphQL 规范以来,它就在前端 Web 开发中迅速流行起来。



为什么这种新技术会突然流行起来?


与传统 REST API 相比,GraphQL 提供了哪些优势?


我们将讨论 GraphQL 的设计原则,比较 GraphQL 与 REST 中的相同请求,并深入探讨 GraphQL 相对其他架构的优点。


为理解 GraphQL 作为 API 架构的好处,我们要讨论 API 在客户端 - 服务器结构中的作用。API(应用程序编程接口)是一个中间层,它允许服务器从客户端接收结构化数据请求,并针对请求的数据发送结构化的响应。设计 API 架构的方法有很多种。


让我们来研究一下促使 GraphQL 适合现代化 Web 应用程序的重要基本设计原则。

二、GraphQL 服务器的设计原则

GraphQL 规范概括了 5 个设计原则,这使其成为现代前端开发的良好解决方案。我们看一下 GraphQL 的设计原则,并以 Facebook 新闻推送作为我们的用例。



  1. 查询为分层结构,使用将查询与响应数据 1 对 1 匹配的分层和嵌套字段格式。查询和响应的形状类似于树,可查询每个项的其他嵌套字段。在 Facebook 的新闻推送中,这种结构允许一个查询返回一个帖子列表、每个特定帖子的评论,以及每个评论的点赞。

  2. 该结构以产品为中心,关注前端希望如何接收数据,并构建交付所需的运行时。这使得 Facebook 的新闻推送可通过一次请求从后端获取需要的所有数据,使服务器按照 GraphQL 的规范从不同的端点获取数据。

  3. 它使用特定于应用程序的类型系统,该系统使开发人员能在执行前确保查询使用了有效类型,并且语法正确。例如,新闻推送的 GraphQL 模式要求字段“user”必须包含一个字符串,而“likes”必须包含一个数字。如果查询试图添加不同类型的输入,GraphQL 将在执行查询前抛出一个错误。

  4. GraphQL 查询是在客户端指定的,因此,客户端确切知道它将以何种格式接收数据。这意味着,如果前端请求的格式是包含用户名、评论和点赞的 post 数据,那么来自 Facebook 新闻推送的请求会构建在一个对象中,而不是像其他架构那样构建多个单独的数据块。

  5. 使用 GraphQL 的服务器结构必须是内省的,或者可由 GraphQL 自己查询。于是才有了像 GraphiQLGraphQL playground 这样的强大工具。这两种工具都可以让 Facebook 开发人员准确地看到在他们的服务器上使用了哪些查询和字段。


为讨论向 GraphQL 的转变,以及这些设计原则如何给开发带来好处。


我们首先深入了解传统的 REST API 架构和它的不足之处。

三、传统的 RESTful 架构

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



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


接下来,让我们看看 GraphQL 规范与 REST 的不同之处,以及它的优点。这些优点使这个新架构成为特别适合解决客户端和服务器之间数据交付问题的解决方案。

四、GraphQL 架构

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



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


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


为了阐明 GraphQL 是如何实现这一点的,让我们分解一下 GraphQL 服务器的结构。

五、GraphQL 服务器

启用 GraphQL 逻辑的服务器端逻辑由定义了服务器功能的 Documents 组成。这些 Documents 包含可执行文件和类型系统定义。顾名思义,类型系统定义为每个数据字段定义可接受的类型和格式输入及结果。


可执行文件包含要处理的可能的操作列表,其中包括操作类型(查询、修改或订阅)、操作名称、要查询或写入的字段和一个选择集,该选择集准确定义了将从操作返回的数据。选择集是 GraphQL 的最大价值所在——它们允许客户端查询特定的数据集并接收包含所请求信息的响应:不多不少。


有关 GraphQL 规范的结构和语法的更多信息,请参阅 GraphQL 的文档


接下来,我们将看下 GraphQL 中查询的结构。

六、GraphQL 查询解析

下面是一个结构化的 GraphQL 查询,用于获取特定书籍的数据,包括作者的姓和名。


GET /graphql?query={ books(id:12) { authors { firstName, lastName } title, yearPublished, length } {   Query {                 //  operation type  books (id:12) {         //  operation endpoint     authors {            //  requested fields        firstName        lastName     }      title     yearPublished        }  }}
复制代码


这一切都可以通过一个查询由 GraphQL 服务器逻辑解析和处理完成。当把它与 REST 架构中相同结构的请求进行比较时,GraphQL 的优势就开始显现出来了。


让我们看看下面的 REST 请求结构,然后重点讨论其中的一些差异!

七、REST 请求解析

要向 REST API 发出相同的请求,客户端首先需要向能够返回图书数据的端点发送一个请求,并将图书 id 作为参数传入:


GET /books/12
复制代码


这个请求可能会返回一个包含特定图书所有数据的对象,例如:


{   “title” : “The Hitchhiker's Guide to the Galaxy”,  “authorID”: 42,  “yearPublished” : 1978,  “length”: 208,  “genre”: “Science Fiction”}
复制代码


在我们的例子里,与相同的 GraphQL 查询相比,该响应有两个缺点:


  1. REST 响应包含类似 genre 这样的额外数据,返回的信息超出了我们的需求。

  2. REST 需要再发送一个请求来获得我们实际上正在查找的数据:这个特定作者的所有书籍。


为了获得这些数据,我们需要使用我们的 authorID 发出一个额外的请求:


GET /authors/42
复制代码


这个请求的响应应该包含我们正在查找的所有数据:


{   “firstName” : “Douglas”,  “lastName”: “Adams”}
复制代码


现在我们已经有了需要的所有书籍和作者数据,响应解析由客户端完成。现在,前端应用程序必须将来自不同端点的数据组合在一起,用于实现期望的功能。总的来说,与 REST API 相比,GraphQL 提供的性能优势可以为前端开发人员带来回报。使用 GraphQL 规范创建服务器可能需要更多的设置以及编写预测性的服务器端逻辑来解析和处理请求。


虽然 GraphQL 的设置成本可能比传统的 REST 架构要高,但是,更易于维护的代码、健壮的开发工具和精简的客户端查询所带来的好处通常会超过成本。


英文原文:


GraphQL vs. REST API Architecture


2020-01-18 07:3016012
用户头像

发布了 741 篇内容, 共 480.5 次阅读, 收获喜欢 1549 次。

关注

评论 5 条评论

发布
用户头像
graphql,首先是一种通信协议,协议中包含类似sql的ql语法;除了是一种协议之外,还有一系列的周边生态,这个生态系统使gql比rest、grpc等更有生命力。文中一句话,很认可:架构成本高了,后期维护成本低。
2020-03-18 11:25
回复
用户头像
做中文翻译那个,中文水平有待提高
2020-01-21 10:29
回复
同感....
2020-02-18 15:10
回复
用户头像
这个没有可比性,graphQL是计算框架,restful是通信协议。
2020-01-20 13:58
回复
不知你这个说法从哪里来的?姑且认识你说的是 graphQL是“技术”框架。我理解的是graphQL和restful都是请求数据的一种风格规范,都是对通信时数据格式进行的约束。
2020-01-21 14:50
回复
没有更多了
发现更多内容

微信朋友圈高性能架构方案

Geek_36cc7c

Kotlin语法手册(三)

寻找生命中的美好

android kotlin 安卓

DGIOT 工业物联网开源平台简介

dgiot

物联网 2月月更 2月日更 dgiot dgiot物联网

虎啸春来!丰树电子与中联重科签署战略合作协议

联营汇聚

阿里云容器服务差异化 SLO 混部技术实践

阿里巴巴云原生

阿里云 Kubernetes 云原生 混部技术

平安保险基于 SPI 机制的 RocketMQ 定制化应用

阿里巴巴云原生

阿里云 云原生 消息队列 开源云工具

Go 语言Web开发很简单:使用模板将视图与逻辑分离

宇宙之一粟

Go 语言 Web应用开发 2月月更

独家下载!阿里云云原生携 10+ 技术专家带来《云原生与云未来的新可能》

阿里巴巴云原生

阿里云 Kubernetes 云原生 电子书

还没有表白神器?情人节来喽,快为心爱的她送上一份专属的礼物吧~

是Dream呀

Python 2月月更

《MySQL入门很轻松》第4章:数据表中能存放的数据类型

乌龟哥哥

数据库 2月月更

剑指Offer——企业级项目中分层的含义与依据及多态的优势

No Silver Bullet

封装 offer 继承 多态 2月月更

甜言蜜语生成器、定时问候邮件机…开源程序员为这个情人节付出太多

腾源会

开源

如何快速构建服务发现的高可用能力

阿里巴巴云原生

阿里云 开源 微服务 云原生

云原生落地大爆发,企业和开发者如何把握先机?

阿里巴巴云原生

阿里云 云原生 ACK ACK Anywhere

国内唯一!阿里云容器服务进入 Forrester 领导者象限

阿里巴巴云原生

阿里云 云原生 容器平台

人人都是 Serverless 架构师 | 现代化 Web 应用开发实战

阿里巴巴云原生

阿里云 Serverless 云原生

为什么start方法不能重复调用?而run方法却可以?

王磊

Java 面试

KubeDL HostNetwork:加速分布式训练通信效率

阿里巴巴云原生

阿里云 云原生 分布式训练 KubeDL

企业为什么要做应用多活?

阿里巴巴云原生

阿里云 云原生 容灾

计算机网络面试知识点

yuexin_tech

面试 计算机网络

详细讲解mybatis的执行流程

编程江湖

mybatis

美团动态线程池实践思路,开源了

yanhom

Java 线程池 动态调整线程池参数 动态线程池 美团线程池

运营给产品送的情人节礼物是?

阿里云弹性计算

产品运营 情人节 轻量征文 用户投稿

Spring Boot Serverless 实战系列 | 性能调优

阿里巴巴云原生

阿里云 Serverless 架构 云原生

给面试加点硬菜:延迟任务场景,该如何提高吞吐量和时效性!

小傅哥

小傅哥 架构设计 Redis 6.0 任务系统

教程直播第8期|一文详解 OceanBase 社区版生态工具 ODP & OCP

OceanBase 数据库

数据库 分布式 直播 OceanBase 开源

DevOps进阶(三)走近 DevOps 工程师

No Silver Bullet

DevOps 敏捷 jenkins 2月月更

SSH远程连接命令执行没反应不报错问题解决(-bash: fork: retry: Resource temporarily unavailable.[资源暂时不可用])

山河已无恙

SSH Linxu 2月月更

专访 OpenKruise 负责人:现在的云原生应用自动化发展到什么程度了?

阿里巴巴云原生

阿里云 开源 云原生

Linux系统编程-进程间通信(mmap内存映射)

DS小龙哥

2月月更 mmap内存映射

流量录制与回放在vivo的落地实践

vivo互联网技术

测试工具 回归测试 流量回放

GraphQL vs REST API 架构,谁更胜一筹?_架构_Michele Moody_InfoQ精选文章