前言

GraphQL官网:https://graphql.org/

GraphQL国内翻译:https://graphql.cn/

  • GraphQL在前端使用较多

GraphQL前端常用工具:https://www.apollographql.com/(适用于Node.js)

Java后端:Graph-Java

1 GraphQL介绍及最佳场景

​ GraphQL 是一种针对 Graph(图状数据)进行查询特别有优势的 Query Language(查询语言),所以叫做 GraphQL。它跟 SQL 的关系是共用 QL 后缀,就好像「汉语」和「英语」共用后缀一样,但他们本质上是不同的语言。GraphQL 跟用作存储的 NoSQL 没有必然联系,虽然 GraphQL 背后的实际存储可以选择 NoSQL 类型的数据库,但也可以用 SQL 类型的数据库,或者任意其它存储方式(例如文本文件、存内存里等等)。

​ GraphQL 最大的优势是查询图状数据。GraphQL 是 Facebook 发明的,可以用 Facebook 做例子。例如说,如果要在 Facebook 上打开我的页面查看我的信息,需要请求如下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
我的名字
我的头像
我的好友(按他们跟你的亲疏程度排序取前 6):
好友 1 的名字、头像及链接
好友 2 的名字、头像及链接
……
我的照片(按时间倒序排序取前 6):
照片 1 及其链接
照片 2 及其链接
……
我的帖子(按时间倒序排序):
帖子 1:
帖子 1 内容
帖子 1 评论:
帖子 1 评论 1:
帖子 1 评论 1 内容
帖子 1 评论 1 作者名字
帖子 1 评论 1 作者头像
帖子 1 评论 2:
……
……
帖子 2:
帖子 2 内容
帖子 2 评论:
……
……

​ 这是一个超级复杂的树状结构,如果用常见的 RESTful API 涉及,每个 API 负责请求一种类型的对象,例如用户是一个类型,帖子是另一个类型,那就需要非常多个请求才能把这个页面所需的所有数据拿回来。而且这些请求之间还存在依赖关系,不能平行地发多个请求,例如说在获得帖子数据之前,无法请求评论数据;在获得评论数据之后,才能开始请求评论作者数据。

​ 如何解决这种问题?一个简单粗暴的办法是专门写一个 RESTful API,请求上述树状复杂数据。但很快新问题就会出现。现在 Facebook 想要做一个新的产品,例如说是宠物,然后要在我的页面上显示我的宠物信息,那这个 RESTful API 的实现就要跟着改。

​ GraphQL 能够很好地解决这个问题,但前提是数据已经以图的数据结构进行保存。例如上面说到的用户、帖子、评论是顶点,而用户跟用户发过的帖子存在边的关系,帖子跟帖子评论存在一对多的边,评论跟评论作者存在一对一的边。这时候如果新产品引入了新的对象类型(也就是顶点类型)和新的边类型,那没有关系。在查询数据时用 GraphQL 描述一下要查询的这些边和顶点就行,不需要去改 API 实现。

​ 说完了 GraphQL 是什么和能解决什么问题,下面说说不够好的地方。

​ 第一,数据必需已经以图的数据结构进行存储才有优势。Facebook 内部有非常好的后端做好了这件事情,而且还内置了基于隐私设置的访问控制。例如说你发的帖子有些是所有人可见的、有些是好友可见的、有些是仅同事可见的,我在打开你的页面时 Facebook 有一个中间层保证了根据我和你的关系我只能看到我该看到的帖子。GraphQL 在这一层之上,所以无论 GraphQL 怎么写我都不可能看到我不该看到的信息。

​ 第二,并不是所有场景都适用于 GraphQL 的,有些很简单的事情就应该用 RESTful API 来实现。Facebook 内部用户增长部门的很多 API 都还不是 GraphQL,因为没必要迁移到 GraphQL。用户增长部门的 API 处理新用户注册、填写短信验证码之类的事情,这些事情都是围绕着一个用户的具体某项或多项信息发生的,根本没有任何图的概念。可以强行写作 GraphQL,但得不到显著的好处。既然老的 API 早就写好了,需要的时候做一些小改动,但没必要重写。

​ 第三,GraphQL 尽管查询的数据是图状数据结构,但实际获得的数据视图是树状数据结构。每一个 GraphQL 查询或更新都有自己的根节点,然后所有的数据都是从根结点展开出去的。查询后获得的数据如果要在前端重新变回图的状态,那前端就不能简单地缓存查询得到的数据,必须用对应的 GraphQL 存储库,然后通过顶点的 ID 把不同节点之间的某些边重新连接起来。

来源:https://www.zhihu.com/question/264629587/answer/949588861

2 GraphQL视频介绍

GraphQL简介,来源:https://www.zhihu.com/question/264629587/answer/2311348659