说说实际工作中 GraphQL 的使用体验
10月 11, 2019
背景 #
接触 GraphQL 是工作中需要有一个项目,用来聚合内部很多其他微服务的接口然后统一暴露给外部使用,在这样的场景下,对项目有几点需求:
- 能够让外部业务方对接方便,当然最好有接口文档。
- 各个业务方可以根据他们自己的需要自己选择字段集合。
- 项目提供的接口可以被不同的语言框架通过 HTTP 调用,比如前端、Python、Go 等。
基于以上的需求,在组内一位大神的提议下,顺理成章的使用了 GraphQL 作为解决方案,经过半年多的迭代维护,今天特来从后端角度说下使用体验。
GraphQL 是什么 #
GraphQL 是一种查询语言,它由 Facebook 创造。它定义了一种新的数据查询方式,客户端可以只指定自己需要的字段进行查询,从而减少整个网络的通信流量,这对 Facebook 这种体量的公司是非常有用的。另外 GraphQL 统一了规范,自带文档,这一点对不喜欢写文档的程序员们非常友好。
我们使用了 gqlgen 来作为 Go 服务 GraphQL 代码的生成器,这样后端只需要定义实际的数据结构和方法的实现即可,对接 GraphQL 查询的部分都可以通过 gqlgen 生成。总体上来说,够用,但是随着这个开源项目的发展还是有一些向下兼容的问题,如果不跟着版本更新,很可能就跟不上发展导致后续迭代难度陡增。
N+1 问题 #
同很多 Web 框架一样,GraphQL 的查询也很容易有 N+1 的性能问题,考虑这样的查询语句:
{
articles {
title
comments {
content
}
}
}
这里的 article
文章列表会有 1 次查询,同时还会有 N 次的每个文章对应的 comments
查询。不过好在 GraphQL 社区提供了 DataLoader 的使用,可以在代码层面将查询操作进行延迟,等确定所有的查询参数时再进行一次实际的查询。DataLoader 也具有缓存的功能,可以将查询过的 where id= xx
数据进行缓存,从而进一步减少了查询次数。
学习难度 #
不得不承认,GraphQL 的学习难度确实大,尤其在后端,因为后端大部分时候是围绕 GraphQL 的实现,是 query 和 mutation 方法的定义者,不像前端只需要写查询(相当于换了一种 Json 语法),后端除了功能实现还需要维护服务框架的稳定迭代,以现在GraphQL 生态来讲,原生支持的后端 Web 框架几乎没有,加上这些项目的高速迭代还很难保证向前兼容,这又额外增加了复杂度需要后端持续学习并融合到现有项目里,有的都需要开始学习 DDL 了,所以学习成本是个问题。
总结 #
实现的复杂度主要在后端,如果我是前端我当然乐意用,但如果我是后端,同时业务迭代速度快的话,开发压力也会很大,也很容易产生性能问题,加上服务端框架层面的生态还是不太健全,项目的生命周期越长,维护难度就会越大,可以看看尤雨溪的回答 - GraphQL 为何没有火起来?。