GraphQL是一种面向数据的API查询风格。javascript
GraphQL是由Facebook主导开发的一款面向数据的API查询语言。客户端只需给他一个描述,而后GraphQL就能从数据库组合出符合描述的数据并返回。前端
在开发中咱们通常都使用的是RESTful API,它是是面向资源的。一般渲染一个页面咱们须要多个资源,REST API请求多个资源时就会载入多个URL,而GraphQL能够经过一次请求就能够获取到须要的全部数据。java
解决痛点:数据库
接口返回数据格式并非调用者(前端)理想型npm
多个资源只用一个请求,减小服务器压力json
数据字段由调用者控制后端
GraphQL 既是一种用于 API 的查询语言也是一个知足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端可以准确地得到它须要的数据,并且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。数组
示例:浏览器
这里以掘金的首页举例,它可能分为这几个资源(文章列表,分类列表,做者榜)bash
REST API
文章列表/articles
[
{
title: 'xxx',
content: 'xxx内容'
}
]
复制代码
分类列表/categories
[
{
id: '1'
name: '前端',
},
{
id: '2'
name: '后端',
},
]
复制代码
做者推荐榜/recommendationAuthor
[
{
id: 1,
username: '张三'
}
]
复制代码
上面是用REST接口来获取首页须要的数据,须要发送3次请求,再看下GraphQL的请求是什么样?
GraphQL查询接口/graphql/query
query getHomePage() {
articleList($first: 0) {
title
content
},
categoryList(){
id
name
},
recommendationAuthorList($limit: 10) {
id
username
},
}
复制代码
经过Graphql只用请求一次就能够拿到所有信息,返回的数据格式都是由调用者控制的,很少很多。
这里先介绍几个GraphQL比较重要的概念,能够参考着GraphQL官网文档看。
操做类型能够是query、mutation、substription ,描述你打算作什么类型的操做。
每个Graphql都有一个query
类型,也可能有一个mutation
类型。他们定义了每个Graphql查询的入口。
有符号32位整数
有符号双精度浮点数
UTF-8字符序列
true或者false
ID标量类型标识一个惟一标识符
type Article{
title: String
author: [User]
}
复制代码
上面我声明了一个GraphQL对象类型,这里声明了两个字段并指定了字段类型。
String是内置的标量类型之一,查询中没法对他进行次级选择。
[User] 表示一个User数组,数组中的每一个项目都是一个User对象。
User对象怎么来的呢?
如Article同样 使用type
关键字声明
type User {
name: String
age: Int
}
复制代码
声明对象有什么用?
经过Query对外提供查询入口时,咱们一般都是以一个对象为一个单位。能够把每一个对象看做成一个接口。
经过Mutation对外提供变动入口。有时你须要传递一整个对象做为新建对象,以前的标量类型就不能知足了。
官网示例:
客户端使用前,咱们须要在服务端定义Schema结构。
PS: 下载太慢时能够先全局安装egg-init脚手架,再执行egg-init --type simple --registry china
使用淘宝镜像生成项目
执行npm i egg-apollo-server --save
在egg项目中添加graphql的相关配置, 详见egg-apollo-server
这里我没有用egg-graphql插件而使用的是egg-apollo-server
PS:config.graphql.subscriptions用来对grapql请求作鉴权的,在此demo里不须要改成false便可
├── app
│ ├── controller
│ │ └── home.js
│ ├── graphql
│ │ ├── article
│ │ │ ├── resolver.js
│ │ │ └── schema.graphql
│ ├── router.js
│ └── service
├── config
│ ├── config.default.js
│ └── plugin.js
├── package.json
└── package-lock.json
复制代码
schema.graphql
定义GraphQL类型和操做
extend type Query {
articleList(first: ID): [Article]
}
type Article {
id: ID
title: String
content: String
author: Author
}
type Author {
name: String
age: Int
}
extend type Mutation {
addArticle(title: String, content: String, author: AddAuthor): Article
}
input AddArticle {
title: String
content: String
}
input AddAuthor {
name: String
age: Int
}
复制代码
resolver.js
实现操做
'use strict';
const list = [
{
id: 1,
content: 'aaa',
title: '',
author: {
name: 'aaa',
age: 18,
},
},
{
id: 2,
content: 'bbb',
title: '',
author: {
name: 'aaa',
age: 18,
},
},
];
module.exports = {
Query: {
articleList: () => {
return list;
},
},
Mutation: {
addArticle(root, params, ctx) {
console.log(params);
params.id = list.length++;
list.push(params);
return params;
},
},
};
复制代码
浏览器打开 http://127.0.0.1:7001/graphql进行调试
PS: 测试前须要关闭csrf保护,不然调试发送的post请求将会被拦截
左侧为查询区,在这里写操做语句。右侧为执行结果。
{
articleList(first: 0){
id
title
content
author{
name
age
}
}
}
复制代码
mutation {
addArticle(title: "title", content: "content", author: {name: "张三", age: 15}){
title
content
id
}
}
复制代码