GraphQL一个新的api查询语言,如何配合GraphiQL调试?
发布于 作者:苏南大叔 来源:程序如此灵动~
苏南大叔最近的文章有提到neo4j是个图形数据库,那么,这个graphql和图形数据库有什么关系呢?是不是图形数据库的查询语言呢?苏南大叔认为:不是,两者没有啥特别的关系。那么,graphql到底是个什么东西呢?如何利用和编写graphql代码呢?这就是本文要讨论的问题。

大家好,这里是苏南大叔的“程序如此灵动”博客,这里讨论苏南大叔和计算机代码的故事。本文就仅仅讨论一个新的技术规范,叫做graphql。本文中的内容,都是基于苏南大叔自己的理解的,并不是graphql的标准答案。所以,仅供参考。而且,本文仅代表发布时的观点,并非永久观点。
本文测试环境:win10,graphql@16。
graphql 是什么?
graphql到底是什么?官方自己的定义是:一种新的api查询语言。

接下来说说苏南大叔的个人观点,
graphql并不是个数据库,也不是个新的某种编程语言,和图形数据库neo4j也没有啥关系。但是,graphql确实引入了一种新的查询语言,或者说是规范。也就是说,graphql和java/php/node等等不冲突,graphql和sqlserver/mysql/sqlite等等也不是替换的关系。graphql是个在不同高级语言里面有相同实现的技术规范,和大家以前已经广泛接受的restful概念是类似的。但是,graphql实现起来是比较复杂的,远超restful的实现难度。所以,官方针对graphql的思路,出品了各种流行语言下的类库。大家可以根据这些类库提供的graphql的功能,再实现具体的逻辑,比如数据库内容的CRUD等等。
graphql 是一种用于 API 的查询语言,对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,减少数据的冗余。
如果再形象点描述的话,
- 大家已经熟知的后端查询的
sql语句,变成另外一种可编程的数据形式,交给前端去决定和调用。 - 后端依据各种编程语言下的
graphql的类库,再去实现数据的各种查询,具体的逻辑就看业务需求了。
查询界面graphiql
下面说一下graphql的查询界面,任何语言形式实现的graphql,都自带这个查询界面。官方命名为:GraphiQL,多了一个i字母。在这个界面上,左侧写要查询的数据(类似sql语句的功能),右侧就会显示出服务器段返回的数据结果了。
这个graphiql的查询界面,并不是必须出现的。仅仅是个调试工具,在生产环境里面,是可以关闭的。如下图所示:

要学习的内容
对于接口调用方(前端/客户端)来说:
因为数据查询的任务,交给了前端(客户端)。所以,对于前端从业人员来说,需要学习这款graphql新查询语言。这个查询语言的复杂程度,可是远超普通的sql的,而且会有类继承之类的概念,对于纯前端人员来说,是个巨大的挑战。
而对于接口编写方(后端/服务器端)程序员来说:
要先定义个schema,也就是给前端规范一个可查询的范围。然后,还要找到对应的编程语言下的graphql的实现。不过,这个不要担心,官方已经列出来了非常全的可选择范围。地址见这里:
https://graphql.org/code/

对于运维人员来说:
基本上就是没事儿偷着乐了。服务器压力会减轻很多,并发数大幅下载。
对于接口文档编写人员来说:
接口文档的要求也没有那么高了,毕竟编写查询语句的时候,都自动提示了。哪里有错误都有直接的错误提示信息,相当的智能。
要发送的数据
对于官方提供的graphiql来说,已经是非常好的调试工具。但是,对于前端(客户端)的请求来说,请求的具体内容是有点区别的。下面的图是具体的对比,当然,这里仅仅是个范例,具体问题请具体分析。

如果确实不知道在自己的代码里面,该post什么数据到接口上的话,可以对GraphiQL的界面,打开f12抓包。然后你就可以充分了解到发生了什么事情了。
基本的结论就是:
- 发送的
header里面,必须指定Content-Type:application/json。 - 发送的数据就是查询语句上面加个
query:,例如:{"query":"<原语句>"}。

可能存在的问题
这里说点题外话,GraphQL这种新的接口定义方式,如果碰上逻辑不严谨的人员,这里可能会出大篓子。下面是苏南大叔的担心:
接口编写者并不控制字段,而接口调用者控制字段。所以,接口调用者只会请求自己的字段,接口编写者会尽量提供全部字段。看出来问题来了么?只需要猜出字段名(也不用猜,探测一下接口即可,apollo自带这种功能),就可以越权访问数据!一些隐私数据字段完全可能就这样不明不白的就被访问到了!
接口的开发和使用人员,都会一脸懵逼,说这事儿和他们没关系!虽然目前还没有出现这方面的漏洞报告,但显然苏南大叔关于GraphQL的担心,并不为过。
参考文献
- https://newsn.net/say/rest-client-java.html
- https://graphql.org/
- https://graphql.org/learn/
- https://graphql.org/code/
总结
graphql这个概念比较颠覆传统的接口请求的思路,虽然和它最接近的概念是restful,但是两者的区别也是非常大的。不但接口的查询者需要学习新的查询语言,接口的编写者也要在传统的CRUD概念上做大量适配。
但是,这个graphql的好处是什么呢?个人觉得最大的被动受益者要属于运维了,因为这个graphql的最大特点就是可以合并请求,原本一个页面上多个请求,在graphql的概念里面,就可以直接发一个请求就可以了。也就是说,接口请求数量会大大降低,运维工程师的压力会直线下降。
本文中的内容,仅仅是从概念宏观层面上,苏南大叔对graphql的个人解读,很有可能有偏颇,所以本文内容仅供参考。更多graphql的文章,请参考苏南大叔的系列文章: