一、GraphQL入门
什么是GraphQL?
GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。
一个 GraphQL 服务是通过定义类型和类型上的字段来创建的,然后给每个类型上的每个字段提供解析函数。例如,一个 GraphQL 服务告诉我们当前登录用户是 me
,这个用户的名称可能像这样:
type Query {
me: User
}
type User {
id: ID
name: String
}
一并的还有每个类型上字段的解析函数:
function Query_me(request) {
return request.auth.user;
}
function User_name(user) {
return user.getName();
}
一旦一个 GraphQL 服务运行起来(通常在 web 服务的一个 URL 上),它就能接收 GraphQL 查询,并验证和执行。接收到的查询首先会被检查确保它只引用了已定义的类型和字段,然后运行指定的解析函数来生成结果。
二、详细学习
1、基本参数类型
基本类型:String、Int、Float、Boolean和ID,可以在schema声明的时候直接使用
[类型]代表数组,例如:[Int]代表整型数组
和js传递参数一样,小括号内定义形参,但是注意:参数需要定义类型
!(叹号)代表参数不能为空(必须传递)
//numDice参数不能为空
type Query {
rollDice(numDice:Int!, numSides:Int):[Int]
}
2、自定义参数类型
GraphQL允许用户自定义参数类型,通常用来描述要获取的资源属性
type Account {
name:String
age:Int
sex:String
}
type Query {
account(name:String):Account
}
3、在客户端访问graphql的接口
代码如下:
js代码:
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
//定义schema 查询和类型
const schema = buildSchema(`
type Query {
getClassMates(classNo: Int!): [String]
account(username: String)
}
`);
//定义查询对应的处理器
const root = {
getClassMates: ({classNo}) => {
const obj = {
2: ['赵六', '田七', '周八']
};
return obj[classNo];
}
};
//创建express应用
const app = express();
//使用express-graphql中间件处理GraphQL请求
app.use('/graphql1', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true, //是否开启GraphiQL界面
}));
//公开文件夹,供用户访问静态资源
app.use(express.static('public'));
//启动express应用
app.listen(4000);
html代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button onclick="getData()"></button>
</body>
<script>
function getData() {
const query = `
query Account($username: String){
account(username: $username)
}
`
const variables = {username:" "}
fetch('/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: query,
variables: variables,
}),
}).then(res => res.json)
.then(json => {
console.log(data);
})
}
</script>
</html>
4、使用Mutations修改数据
查询使用query,修改数据使用Mutations
input AccountInput {
username: String!
age: Int!
sex: String
salary: Float
}
type Mutation {
createAccount(input: AccountInput!): Account
updateAccount(input: AccountInput!): Account
}
5、认证与中间件
代码如下:
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
//定义GraphQL Schema查询类型 mutations
const schema = buildSchema(`
input AccountInput {
name: String
age: Int
sex: String
department: String
}
type Account {
name: String
age: Int
sex: String
department: String
}
type mutation {
createAccount(input: AccountInput!): Account
updateAccount(id: ID!, input: AccountInput!): Account
}
//必须得有query类型,否则会报错
type query {
accounts: [Account]
}
`);
//模拟数据库功能
const fakeDB = {};
//定义查询对于的处理器
const root = {
accounts(){
return fakeDB;
},
createAccount: ({ input }) {
//模拟数据库保存
fakeDB[input.name] = input;
//返回保存的结果
return fakeDB[input.name];
},
updateAccount: ({ id, input }) => {
//模拟数据库更新
const updateAccount = Object.assign({}, fakeDB[id], input);
fakeDB[id] = this.updateAccount;
//返回更新的结果
return updateAccount;
}
};
const app = express();
//中间件处理GraphQL请求
const middleware = (req, res, next) =>{
if(req.url.indexOf('/graphql') && req.headers.cookie.indexOf('auth') === -1){
res.send(JSON.stringify({
error:"您没有权限访问这个接口"
}))
return ;
}
next();
};
app.use(middleware)
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
app.listen(4000);
6、Constructing Types
使用Graphql ObjectType定义type(类型)
使用Graphql ObjectType定义query(查询)
代码量会上升,但是可维护性会提高
三、具体实例
1、Hello World实例
准备工作:
安装依赖:
npm init -y
npm install graphql express express-graphql -S
//运行项目
node helloworld.js
代码如下:
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
//定义GraphQL Schema查询类型
const schema = buildSchema(`
type Query {
hello: String
}
`);
//定义查询对于的处理器
const root = {
hello: () => {
return 'Hello world!';
},
};
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
app.listen(4000);
运行效果如下: