本文介绍了GraphQL,它是一种用于API的查询语言,有着精确获取所需数据、提高查询效率等优点。但GraphQL也存在一些问题,如生态不足、性能优化困难等。
什么是 GraphQL
GraphQL(Graph Query Language,GQL) 既是一种用于 API 的查询语言,可以对你的 API 中的数据提供一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。
举个例子?
在 GraphQL 中请求数据十分简单,只需要找到你需要的字段并把它加进请求中,比如:
1 | }---Result }} |
也可以给这个查询取个名字,这不会影响你获取到的结果,比如:
1 | query GetAppInfo } |
而在对数据进行增加修改等操作时,我们一般使用 mutation:
1 | mutation AddUser ) }---Result }} |
借助强大的开发工具,你甚至不需要知道具体的编写规则,只要动动手勾选你要的数据,请求就已经为你编写好了!
而对于服务端,我们只需要定义对象和类型,再为对应的字段编写函数获取数据就OK了!
有什么优点?
准确获取梦想中的数据:客户端通过一个 GraphQL 请求就能准确获得想要的数据,不多不少,而且总是返回可预测的结果。
一次吃到饱:GraphQL 查询不仅能够获得资源的属性,还能沿着资源间的引用做进一步查询,可以通过一次请求就获取你应用所需的所有数据,而不用多次载入不同的URL。
安全感拉满:GraphQL 使用类型来保证应用只请求可能的数据,保证数据的正确性和一致性,还提供清晰的辅助性错误信息。应用可以使用类型,而避免编写手动解析代码。再也不用担心 TypeError 了
API 版本更新?我全都要!你可以给你的 GraphQL API 添加字段和类型而无需影响现有查询。老旧的字段可以废弃,从工具中隐藏。通过使用单一演进版本,GraphQL API 使得应用始终能够使用新的特性,并鼓励使用更加简洁、更好维护的服务端代码。(当然,如果你要对已有字段大改,还是免不了那些麻烦的操作的)
高级用法
BFF ,全称是「Backend For Frontend」,顾名思义就是面向前端的后端。前端同学可以开始自行完成数据组装工作,从而与服务端在适配层完成解耦,大部分字段的变更都可以由前端同学闭环完成,再没有大量的沟通成本。这样做带来的好处是,当项目要进行多端的开发或者是前端要进行大改,后端几乎不需要进行改动。
API 网关,GraphQL 作为一门中心化的查询语言,对外只暴露一个端点,我们可以将它作为 API 网关,对如微服务接口等进行组合,对外提供方便统一的使用体验。
联邦与超图,联邦可以将多个独立的 GraphQL 子图进行组合,并形成一个超图,客户端访问时会自动从子图中获取需要的数据。
一些缺点
生态,GraphQL 的生态可以说是一言难进,尽管用的人还不少,一些大公司也有在使用,但讨论的人、相关的工具和资料就是非常少。宣传的时候说 GraphQL 有强大的开发者工具,但事实是目前绝大部分的 API 工具都不支持它;宣传的时候说 GraphQL 不受编程语言和数据源的限制,但事实是除了 JavaScript 以外大部分语言都仅限于支持,可以参考的资料非常少。这些问题即使是在 GraphQL 最受关注的那几年也没好到哪去,更不用说现在了。
性能,N+1 问题,大量反射带来的性能消耗等,在实践中写一个 GraphQL 很简单,但想把它做好、对性能进行优化却非常困难。此外,GraphQL 的 Schema 定义不能满足所有场景需求、安全防护比较复杂等都是实践中可能会遇到的问题。相关的资料又少,基本只能靠自己摸索(其实也算是生态的问题?)
总结
GraphQL 很炫酷,也可以在某些特定的场景脱颖而出,但也存在一些生态和实践上的问题。许多介绍它的文章号称轻松干掉 RESTful,我个人看来还是差点意思。目前它或许更适合用在一些后台管理、低代码等不太复杂的项目。