什么是graphql
首先,让我们看下面这张图:
以往的模式是, client端和server端直接互相通信, 很多情况下, 作为前端开发, 往往是服务端返回什么数据, 我们只能被动接受. 可能我们只需要一个参数person
, 可服务端会返回很多不相关的其他信息, 这不仅仅增加了网络负担, 更加大了前端维护的工作量.
现在不同了, graphql
改变了这种交互模式, 它作为中间件, 可将服务端预发送的数据转成客户端真正需要的, 比如我们只需要客户的name
, 通过Apollo
发送请求, 服务端再通过GraphQL Server
的处理, 返回的数据便只会包含name
. 具体, 可见下面的例子
正文
安装
在命令行, 执行如下命令:
# 创建c
mkdir graphql-example
# 进入该目录
cd graphql-example
npm install express
# 安装如下俩包, 因服务端需要express-graphql帮助它弄明白graphql的语法
npm install graphql express-graphql
成功安装后, 通过以下命令
code .
快速用vscode
打开graphql-example
项目
创建服务
在项目下, 创建server
文件夹,并在该文件夹下创建app.js
, 该js的内容如下所示:
const express = require('express');
const app = express();
app.listen(4000, () => {
console.log('Listening for requests on port 4000')
})
完成之后, 输入以下命令, 若输出Listening for requests on port 4000
, 则表示服务启动成功
推荐使用nodemon, 可监听代码变化, 自动显示更改后的效果, 如webpack的热更新, 无需重启服务器.
npm install nodemon -g
服务嵌入graphql
继续在app.js
添加如下代码
const { graphqlHTTP } = require('express-graphql')
app.use('/graphql', graphqlHTTP({
}))
app.use
是express
中间件的用法, 你可以将服务器express
想象成某邮局总经理, 当需要将某邮件发往湖北时, 他会交给湖北负责人去处理, 这段代码表示, 若客户端请求地址为/graphql
时, 则交给graphqlHTTP
去处理, 现在让我们启动服务http://localhost:4000/graphql
, 看会输出什么
{"errors":[{"message":"GraphQL middleware options must contain a schema."}]}
这段错误提示我们需要创建schema
, schema是种数据结构, 比如你定义Book
时, 往往需要在该Book
上添加name
等信息, 这便是schema
创建schema.js
schema.js
代码如下所示:
const graphql = require('graphql')
const { GraphQLObjectType, GraphQLString, GraphQLSchema } = graphql
const _ = require('lodash')
var persons = [
{name: 'zhangsan', sex: 'male', id: "1"},
{name: 'lisi', sex: 'male', id: "2"},
{name: 'lili', sex: 'female', id: "3"}
]
// 创建Person结构体
const PersonType = new GraphQLObjectType({
name: 'Person',
fields: () => ({
id: {type: GraphQLString},
name: {type: GraphQLString},
sex: {type: GraphQLString}
})
})
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
person: {
type: PersonType,
args: {
id: {type: GraphQLString}
},
resolve(parent, args) {
// args.id
// 从数据库活其他资源里拿到数据
return _.find(persons, {id: args.id})
}
}
}
})
module.exports = new GraphQLSchema({
query: RootQuery
})
注意点: PersonType
的fields
是用函数包裹的返回对象, 其原理与vue
的data
函数类似, 因为会有多个实例person
, 而RootQuery
作为根查询, 它永远只会有一个, 所以fields
为普通对象
服务引入schema
在app.js
里添加如下代码
const schema = require('../schema/schema.js')
app.use('/graphql', graphqlHTTP({
schema
}))
刷新http://localhost:4000/graphql
, 网页报如下图错误:
服务添加graphiql
在app.js
里添加如下代码:
app.use('/graphql', graphqlHTTP({
schema,
graphiql: true // 查询使用iql方式查询数据
}))
再次刷新http://localhost:4000/graphql
, 会看到如下界面:
我们在后续课程继续, 今天先到这里