graphql 一日游

graphql

是什么?

GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

为什么?

请求你所要的数据不多不少

向你的 API 发出一个 GraphQL 请求就能准确获得你想要的数据,不多不少。 GraphQL 查询总是返回可预测的结果。使用 GraphQL 的应用可以工作得又快又稳,因为控制数据的是应用,而不是服务器。

获取多个资源只用一个请求

GraphQL 查询不仅能够获得资源的属性,还能沿着资源间引用进一步查询。典型的 REST API 请求多个资源时得载入多个 URL,而 GraphQL 可以通过一次请求就获取你应用所需的所有数据。这样一来,即使是比较慢的移动网络连接下,使用 GraphQL 的应用也能表现得足够迅速。

描述所有的可能类型系统

GraphQL API 基于类型和字段的方式进行组织,而非入口端点。你可以通过一个单一入口端点得到你所有的数据能力。GraphQL 使用类型来保证应用只请求可能的数据,还提供了清晰的辅助性错误信息。应用可以使用类型,而避免编写手动解析代码。

API 演进无需划分版本

给你的 GraphQL API 添加字段和类型而无需影响现有查询。老旧的字段可以废弃,从工具中隐藏。通过使用单一演进版本,GraphQL API 使得应用始终能够使用新的特性,并鼓励使用更加简洁、更好维护的服务端代码。

使用你现有的数据和代码

GraphQL 让你的整个应用共享一套 API,而不用被限制于特定存储引擎。GraphQL 引擎已经有多种语言实现,通过 GraphQL API 能够更好利用你的现有数据和代码。你只需要为类型系统的字段编写函数,GraphQL 就能通过优化并发的方式来调用它们。

怎么用?

首先理解一些基本概念:
Schema 和类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// schame.gql
type User{
account: String
name: String
}
type todolist: {
time: String!
content: String!
}
type Query{
userinfo(account: String): User
todolists: [todolist]
}
type Mutation {
registry(account:String, name:String): User
}

可以把他理解为一个供前端查询的入口文件,里面包含了类型系统,查询函数和变更函数。服务端收到请求后调用对应resolver函数,然后返回对应type数据。

1
2
3
4
5
6
7
8
query {
userinfo {
name
}
todolists{
content
}
}

前端调用时,可以通过查询gql,获取对应数据,如上,只发一次请求能同时获取userinfo和todolist的数据。
在实现上,其实就是结构化query数据,然后使用fetch/xmlhttprequest发送。服务端接收到之后再解构出对应的请求操作,返回数据。

一点思考

  • 在使用apollo-react时觉得他们Query、Mutation组件真好用,自带loading和error处理。打算在普通接口项目里结合Redux试一下。

  • resolve函数中可以从多个数据源获取数据,可以是MySQL,redis,或者其他第三方api,提供了一定的便利。可以用作一个统一的接口集合,打造一个多App的中台服务。

  • 接口迭代升级方便,可快速为type增删字段。接口测试时同理,但暂时没有找到相关的成熟工具。

  • 关于一次请求所有所需数据和只获取所需数据,在网络层面1、节省了请求数量;2、缩小了所发送数据包的体积。但是缺点依然很明显

    • resolve函数必须获取全部所需数据才能供查询筛选,比如获取用户信息,也许前端只要id&username,但是后端的查询得select * from user;有时也许还得join多张表,这点就没有定制接口来得高效
    • 如果一次请求中包含了很耗时的操作,比如获取用户信息同时调第三方接口获取todolist详细数据。之前我们拆分2个请求可以做到先把用户部分渲染出来,然后列表数据慢慢loading。graphql想做到这种效果依然要创建两次请求。在没有形成调用规范之前,调用方很可能就忽略这部分耗时接口,导致页面渲染慢。
    • 随着项目逐渐庞大,入口文件拆分也是问题。如果作为一个业务中台,多业务的接口权限要如何限制?

总结

graphql很好,让前端支配服务端又迈了一步,但是就像最早我们抛弃服务端渲染template,转为前后端分离,现在又开始做ssr,值不值得用还等根据业务仔细考量。g