苏南大叔最近的文章有提到neo4j是个图形数据库,那么,这个graphql和图形数据库有什么关系呢?是不是图形数据库的查询语言呢?苏南大叔认为:不是,两者没有啥特别的关系。那么,graphql到底是个什么东西呢?如何利用和编写graphql代码呢?这就是本文要讨论的问题。

苏南大叔:GraphQL一个新的api查询语言,如何配合GraphiQL调试? - graphql是什么
GraphQL一个新的api查询语言,如何配合GraphiQL调试?(图6-1)

大家好,这里是苏南大叔的“程序如此灵动”博客,这里讨论苏南大叔和计算机代码的故事。本文就仅仅讨论一个新的技术规范,叫做graphql。本文中的内容,都是基于苏南大叔自己的理解的,并不是graphql的标准答案。所以,仅供参考。而且,本文仅代表发布时的观点,并非永久观点。

本文测试环境:win10graphql@16

graphql 是什么?

graphql到底是什么?官方自己的定义是:一种新的api查询语言。

苏南大叔:GraphQL一个新的api查询语言,如何配合GraphiQL调试? - graphql官方网站
GraphQL一个新的api查询语言,如何配合GraphiQL调试?(图6-2)

接下来说说苏南大叔的个人观点,

  • graphql并不是个数据库,也不是个新的某种编程语言,和图形数据库neo4j也没有啥关系。但是,graphql确实引入了一种新的查询语言,或者说是规范。也就是说,graphqljava/php/node等等不冲突,graphqlsqlserver/mysql/sqlite等等也不是替换的关系。
  • graphql是个在不同高级语言里面有相同实现的技术规范,和大家以前已经广泛接受的restful概念是类似的。但是,graphql实现起来是比较复杂的,远超restful的实现难度。所以,官方针对graphql的思路,出品了各种流行语言下的类库。大家可以根据这些类库提供的graphql的功能,再实现具体的逻辑,比如数据库内容的CRUD等等。
graphql 是一种用于 API 的查询语言,对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,减少数据的冗余。

如果再形象点描述的话,

  • 大家已经熟知的后端查询的sql语句,变成另外一种可编程的数据形式,交给前端去决定和调用。
  • 后端依据各种编程语言下的graphql的类库,再去实现数据的各种查询,具体的逻辑就看业务需求了。

查询界面graphiql

下面说一下graphql的查询界面,任何语言形式实现的graphql,都自带这个查询界面。官方命名为:GraphiQL,多了一个i字母。在这个界面上,左侧写要查询的数据(类似sql语句的功能),右侧就会显示出服务器段返回的数据结果了。

这个graphiql的查询界面,并不是必须出现的。仅仅是个调试工具,在生产环境里面,是可以关闭的。

如下图所示:

苏南大叔:GraphQL一个新的api查询语言,如何配合GraphiQL调试? - 查询界面
GraphQL一个新的api查询语言,如何配合GraphiQL调试?(图6-3)

要学习的内容

对于接口调用方(前端/客户端)来说:
因为数据查询的任务,交给了前端(客户端)。所以,对于前端从业人员来说,需要学习这款graphql新查询语言。这个查询语言的复杂程度,可是远超普通的sql的,而且会有类继承之类的概念,对于纯前端人员来说,是个巨大的挑战。

而对于接口编写方(后端/服务器端)程序员来说:
要先定义个schema,也就是给前端规范一个可查询的范围。然后,还要找到对应的编程语言下的graphql的实现。不过,这个不要担心,官方已经列出来了非常全的可选择范围。地址见这里:
https://graphql.org/code/

苏南大叔:GraphQL一个新的api查询语言,如何配合GraphiQL调试? - 支持的高级编程语言
GraphQL一个新的api查询语言,如何配合GraphiQL调试?(图6-4)

对于运维人员来说:
基本上就是没事儿偷着乐了。服务器压力会减轻很多,并发数大幅下载。

对于接口文档编写人员来说:
接口文档的要求也没有那么高了,毕竟编写查询语句的时候,都自动提示了。哪里有错误都有直接的错误提示信息,相当的智能。

要发送的数据

对于官方提供的graphiql来说,已经是非常好的调试工具。但是,对于前端(客户端)的请求来说,请求的具体内容是有点区别的。下面的图是具体的对比,当然,这里仅仅是个范例,具体问题请具体分析。

苏南大叔:GraphQL一个新的api查询语言,如何配合GraphiQL调试? - 发送的数据
GraphQL一个新的api查询语言,如何配合GraphiQL调试?(图6-5)

如果确实不知道在自己的代码里面,该post什么数据到接口上的话,可以对GraphiQL的界面,打开f12抓包。然后你就可以充分了解到发生了什么事情了。

基本的结论就是:

  • 发送的header里面,必须指定Content-Type:application/json
  • 发送的数据就是查询语句上面加个query:,例如:{"query":"<原语句>"}

苏南大叔:GraphQL一个新的api查询语言,如何配合GraphiQL调试? - 数据发送结果对比
GraphQL一个新的api查询语言,如何配合GraphiQL调试?(图6-6)

可能存在的问题

这里说点题外话,GraphQL这种新的接口定义方式,如果碰上逻辑不严谨的人员,这里可能会出大篓子。下面是苏南大叔的担心:

接口编写者并不控制字段,而接口调用者控制字段。所以,接口调用者只会请求自己的字段,接口编写者会尽量提供全部字段。看出来问题来了么?只需要猜出字段名(也不用猜,探测一下接口即可,apollo自带这种功能),就可以越权访问数据!一些隐私数据字段完全可能就这样不明不白的就被访问到了!

接口的开发和使用人员,都会一脸懵逼,说这事儿和他们没关系!虽然目前还没有出现这方面的漏洞报告,但显然苏南大叔关于GraphQL的担心,并不为过。

参考文献

总结

graphql这个概念比较颠覆传统的接口请求的思路,虽然和它最接近的概念是restful,但是两者的区别也是非常大的。不但接口的查询者需要学习新的查询语言,接口的编写者也要在传统的CRUD概念上做大量适配。
但是,这个graphql的好处是什么呢?个人觉得最大的被动受益者要属于运维了,因为这个graphql的最大特点就是可以合并请求,原本一个页面上多个请求,在graphql的概念里面,就可以直接发一个请求就可以了。也就是说,接口请求数量会大大降低,运维工程师的压力会直线下降。

本文中的内容,仅仅是从概念宏观层面上,苏南大叔对graphql的个人解读,很有可能有偏颇,所以本文内容仅供参考。更多graphql的文章,请参考苏南大叔的系列文章:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。