GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。
Why GraphQL
GraphQL 的出现主要是针对于传统的 REST API。传统的 REST API 使用资源实体的概念来划分各个数据实体,当我们需要请求数据的时候,我们往往需要发送多个请求来获取所需要的数据,一般来说,实体当中往往与其它不同类型的实体有着各样的关系。
例如我们需要展示各个用户所编写的博客文章,这需要获取博客的数据以及用户的数据。如果我们通过 REST API 获取,我们首先需要通过 GET /api/posts
获取所有的文章,返回的数据中就包含了文章的相关信息,如标题,内容,创建时间,以及作者的 id。根据获取的作者 id,我们需要根据每一个用户 id,发送请求 GET /api/users/:id
获取每个作者的信息。所以这样单一个展示页面,我们就可能需要发送大量的请求来获取数据。如果这个情况发生在需要数据现场渲染页面的网站,就比较尴尬,尤其是当网络情况较差时。
而使用 GraphQL 的话,只需要单个 Query 即可
|
|
另外传统的 API 在前后端进行接口交互时,往往需要文档来进行沟通交流,通过文档上面的定义和描述,来告诉前端接口到底长什么样,可以获取怎样的数据,以及怎样获取数据。然而文档的质量参差不齐,什么经常存在信息缺失的情况,尤其是需要人工编写的接口描述~~(给你写个类型信息和返回信息都不愿意)~~。尽管有着 Swagger 这些接口文档自动生成的工具,但是还是需要后端开发者付出额外的精力来添加描述信息。而如果写 GraphQL 的话,写一个 Scheme 就可以把支持的类型及其属性都清楚地暴露出去,只要再完善一下其中的 Query 以及 Mutation 内容,即可以把 GraphQL 支持的查询和更改操作都清楚地暴露出来。这些内容都可以通过算是内置的辅助工具 GraphiQL,进行文档的查询,以及实际的尝试。
How
to build
如何编写一个 GrahpQL 服务呢?我们首先需要定义好它的 Schema,包括其定义的类型(Type),输入类型(Input)。在 GraphQL 里面,服务能够支持的查询和更改操作,也是类型,分别是 Query 和 Mutation。
- Type: 每个类型由多个属性组成,每个属性包含一个名字,以及该属性字段的类型,该类型可以为基本类型(Int, String, Boolean, Float, ID),数组,或者是自定义的对象类型
- Input: 输入类型也是一个 Type
- Query: 表示服务支持的查询内容,每个属性表示某个 query,其类型则为返回类型,可以接收参数
- Mutation: 表示服务支持的更改操作,每个属性表示操作名,需要接收输入类型的参数,其类型为返回类型
以下为一个关于 todo 的 GraphQL Schema
|
|
to use
怎么使用 GraphQL 服务呢?
Query
需要查询数据时,我们只需要通过花括号把需要的类型和字段的列举出来即可。当需要传入变量,我们可以在 query 处进行定义,然后在变量处进行值传递。
|
|
Mutation
进行数据更改时,也是类似,传入变量,调用相应的 mutation 方法即可,另外根据需要,我们还可以选择返回的属性。
|
|
to implement
怎样快速搭一个 GraphQL 服务出来呢?当然是采用动态语言最快了,而其中,又自然是选择使用 GraphQL 最多的 JavaScript 语言实现起来最快。
这里我们使用 express 来提高 http 服务,使用 express-graphql 来搭建 GraphQL 服务
|
|
然后就是一把梭地实现,首先构建 GraphQL Schema,然后搭建 http 服务,构建并绑定一个 GraphQL handler,启动服务,完。
|
|
实现就这么简单 2333
后记
在写这篇博客的时候,其实写到后面有点点迷茫,所谓的 GraphQL 真的是这么好吗?如果真的这么好,为什么当前主流的前后端分离,后端接口的方式还是用传统方式的类 RESTful API 的方式来设计和实现呢?
其实回过头看上面举出的例子,那些所谓的需要多次请求才获取到的数据,其实本质上也是因为后端考虑要获取多个数据,才将其整合在一起,作为一个新的独立的 endpoint 来暴露出来的。换句话,其实传统的 API 也可以做到,只需要再写一个 endpoint,专门为这个情况设置独立的 handler。
不过这种专门设置一个新的 endpoint 也未免太过不够 elegant,而且 GraphQL 对我这种还没经历过实际项目的新手来说,最大的优点,还是其自带的 GraphiQL 吧,一个带 ui 的 playground 提供给使用者来了解 API 中支持的类型,查询和变更操作,并且可以随时进行尝试,实在吸引。
所以以后如果需要到 GitHub 挖点数据的时候,不妨把请求方式从其传统的 REST API 上搬到 GraphQL 当中。这样就不需要再在命令行或者是 Postman 的方式来发请求尝试,直接在网页端界面解决。