GraphQL是什么

GraphQL是Facebook在2012年创建、2015年形成规范的一种应用层查询语言,它具有很多优点:客户端可以自定义查询语句,通过自定义不仅提高了灵活性,而且服务端只返回客户端所需要的数据,减少网络的开销,提高了性能;服务端收到客户端的请求,首先做类型检查,及时反馈,而且更加安全;自动生成文档,降低维护成本;服务端通过新增字段,Deprecated字段,避免版本的繁杂和紊乱。然而上面所述也都是Rest API弊端,GraphQL却能很好的解决他们。


GraphQL不与任何数据库或存储引擎绑定,而且已经有很多编程语言都提供了类库对GraphQL的支持,如NodeJs、Java、PHP、Ruby、Python、Scala、Clojure、Go、Net、Elixir、Swift等。GraphQL更关注的是前端交互,因此你可以在你现有的系统上做改造。


Github API迁移至GraphQL

GitHub的Rest API做的非常优秀,一直是行业中的API样板,然而在2016的GitHub全球大会上推出了基于GraphQL的API v4,为什么弃Rest而采用GraphQL?官方的描述是这样的

Why is GitHub using GraphQL?

GitHub is moving to GraphQL for v4 of our API because it offers significantly more flexibility for our integrators. The ability to define precisely the data you want—and only the data you want—is a powerful advantage over the REST API v3 endpoints.

GraphQL is a new way to think about building and querying APIs. Rather than construct several REST requests to fetch data that you’re interested in, you can often make a single call to fetch the information you need.

有GitHub和Facebook这样的巨头领航,猜想GraphQL将是继Rest之后的又一API开发巨大的飞跃。其实Pinterest、Intuit、Coursera、Shopify都已经开始在使用GraphQL了。


GraphQL查询

Graph的查询语句非常类似JSON,如客户端的查询语句

{
user{
name
sex
}
}

上述语句的目的是查询用户信息的name和sex字段数据,服务端返回结果如

{
"data": {
"user": {
"name": "zhaiqianfeng",
"sex": "男"
}
}
}

当客户端使用如下查询语句时

{
user{
name
intro
}
}

服务端返回的结果如

{
"data": {
"user": {
"name": "zhaiqianfeng",
"intro": "博主,专注于Linux,Java,nodeJs,Web前端:Html5,JavaScript,CSS3"
}
}
}

哈哈,是不是客户端完全自由了,可以根据自己特定的业务来获取数据。

几个概念

GraphQL中非常重要的一个概念是Schema,如果你了解XML Schema的话,就非常容易理解GraphQL的Schema了,Schema由服务端来定义,用于定义API接口,并依靠Schema来生成文档以及对客户端请求进行校验。Schema只是一个概念,它是由各种数据类型及其字段组成,而每个类型的每个字段都有相应的函数来返回数据,这是其灵活的关键所在,如Schema

type User{
name: String
sex: String
intro: String
}
type Query {
user:User
}

上面定义了两个类型,User和Query:User有三个字段分别是name、sex和intro;Query是个特殊的类型,用于查询数据,内含user字段;这些类型中的字段都有自动生成的函数来返回数据,函数类似:

function User_name(user){
return user.getName();
}
function User_sex(user){
return user.getSex();
}
function User_intro(user){
return user.getIntro();
}
function Query_user(request){
return request.user;
}

因此当服务端接收到客户端的如下查询语句

{
user{
name
sex
}
}

会调用上面的函数组合来返回数据。下面让我们来使用NodeJs来做个演示….

GraphiQL示例

我们先以express框架来示例,以GraphiQL为工具,方便调试和查看。GraphiQL(/ˈɡrafək(ə)l/)是基于浏览器交互的的GraphQL IDE。首先需要安装相应类库

npm install express express-graphql graphql
// get-start/GraphiQL.js
var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
//定义schema
var schema = buildSchema(`
type User{
name: String
sex: String
intro: String
}
type Query {
user:User
}
`);
//定义服务端数据
var root= {
user: {
name: 'zhaiqianfeng',
sex: '男',
intro: '博主,专注于Linux,Java,nodeJs,Web前端:Html5,JavaScript,CSS3'
}
};
var app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true, //启用GraphiQL
}));

app.listen(4000, () => console.log('请在浏览器中打开地址:localhost:4000/graphql'));

运行

node get-start/GraphiQL.js

在浏览器打开地址,即可调用①输入查询语句,还有代码提示哦,②执行查询,③显示结果,④查看文档,⑤客户端参数,如下图


GraphQL自解析

当然,为了方便验证GraphQL的解析,你也可以直接在服务端来解析查询

// get-start/console.js
var { graphql, buildSchema } = require('graphql');
//定义schema
var schema = buildSchema(`
type User{
name: String
sex: String
intro: String
}
type Query {
user:User
}
`);
//定义服务端数据
var root= {
user: {
name: 'zhaiqianfeng',
sex: '男',
intro: '博主,专注于Linux,Java,nodeJs,Web前端:Html5,JavaScript,CSS3'
}
};
//解析查询
graphql(schema, '{\
user{\
name\
intro\
}\
}', root).then((response) => {
console.log(response);
});

运行

node get-start/console.js

输出

{ data:
{ user:
{ name: ‘zhaiqianfeng’,
intro: ‘博主,专注于Linux,Java,nodeJs,Web前端:Html5,JavaScript,CSS3’ } } }

从这篇文章开始,我将进行一个GraphQL系列。