现有的问题
1.颗粒度问题
- 场景的复杂,不同终端的需求不一样,需要的字段不一样,颗粒度也不一样
- 多个接口合并问题
2.不同版本问题
- 多个版本参数与返回值不一样
3.通信双向问题接口定义
- 接口定义规范问题
4.组件状态需要分别管理
- 父子关系需要的传递问题
- 各个组件需要分发接口
graphQL作用
1.定义
前后端数据查询方式的规范
- 自由组合,定义命名
- 自由调整参数,返回值
- 定义订阅与监听响应事件,解决双向监听
- 有效的合并一个接口
2.例子
1. query查询
# 直接调接口
query {
hello
}
# 执行结果
{
"data": {
"Hello world!"
]
}
# 修改返回名称
query {
helloNew:hello
}
# 执行结果
{
"data": {
helloNew:"Hello world!"
}
# 查询指定字段
query {
books {
title,
author
}
}
### 执行结果
{
"data": {
"books": [
{
"title": "abc",
"author": "xxxx"
}
]
}
# 合并两个接口参数
query {
books {
title,
author
},
helloNew:hello
}
### 执行结果
{
"data": {
"books": [
{
"title": "abc",
"author": "xxxx"
}
],
helloNew:"Hello world!"
}
2.Mutation 动作:新增修改删除
# 创建方法
mutation {
createBook (title:"111",author:"2222"){
id
}
}
# 参数可以省略一部分
mutation {
createBook (title:"111"){
id
}
}
3.subscribe 基于webstock的订阅发布机制
# 执行后 进入listening。。。等待监听模式
#调用mutation方法变化数据,会自动触发
subscription {
subsBooks
}
基于apollo-server代码实现
const { ApolloServer, gql, PubSub, withFilter } = require('apollo-server');
const pubsub = new PubSub() //实例化一个订阅发布对象
const typeDefs = gql`
type Query {
hello: String,
books: [Book],
book(id : String) : Book
}
type Book {
id:String
title: String
author: String
}
type Mutation {
createBook(title: String, author: String): Book!,
clearBook : Boolean
}
type Subscription {
subsBooks : Boolean,
}
`;
//books 对象后续可以调整为 数据库操作
// clearBook():Book
const books = (
() => Array(5).fill().map((v, i) => ({
id: '' + i,
title: 'Title' + i,
author: 'Author' + i
}))
)()
const resolvers = {}
resolvers.Query = {
hello: () => 'Hello world!',
books: () => books,
book: (parent, { id }) => {
return books.find(v => v.id === id)
}
}
resolvers.Mutation = {
createBook: (parent, args) => {
const book = { ...args, id: books.length + 1 + '' }
books.push(book)
// 发布订阅消息
pubsub.publish('UPDATE_BOOK', {
subsBooks: true
})
return book
},
clearBook: () => {
books.length = 0
pubsub.publish('UPDATE_BOOK', {
subsBooks: true
})
return true
}
}
resolvers.Subscription = {
subsBooks: {
// 过滤不需要订阅的消息
subscribe: withFilter(
//这里通过UPDATE_BOOK 主键过滤监听事件
(parent, variables) => pubsub.asyncIterator('UPDATE_BOOK'),
(payload, variables) => true
)
},
}
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`服务启动: ${url}`);
});