本文是graphql极简入门教程的第九篇,并且也是最后一篇,内容主要讲述graphql的实时订阅功能。
graphql极简入门教程目录:
- 第一篇:基于react和graphql-yoga搭建前后端,并实现一个hello world
- 第二篇:基于prisma及sqlite,通过playground创建及查询数据
- 第三篇:在react中执行graphql的新增和查询操作
- 第四篇:react添加路由导航、前后端搜索功能
- 第五篇:添加分页及排序功能
- 第六篇:后端编写用户登录及注册功能
- 第七篇:前端对接用户系统
- 第八篇:前后端接入github的Oauth系统
- 第九篇:graphql实时订阅
实时graphql订阅
graphql的实时订阅是基于WebSockets技术实现,前端将会与后端进行一个长连接通讯,具体的描述也请查看阮一峰老师的教程👉🏻WebSocket 教程,笔者在这就不过多赘述了。
在后面的内容中,将会实现用户创建新链接后,发送该事件的实时订阅机制。
定义后端数据结构
与其它类型一样,实时订阅有一个Subscription类。
因此根据需求,在src/server/schema.graphql中有如下的定义,该订阅将会返回一个链接(Link)类型数据:
type Subscription {
newLink: Link
}
后端具体实现
在graphql-yoga中,无需引入额外的包来实现实时订阅,你直接引入createPubSub即可。为了方便后期调用,因此也将订阅(pubSub)也挂载在上下文(context)中:
// ...
const Subscription = require('./resolvers/Subscription');
const { getUserId } = require('./utils');
const {createPubSub} = require("graphql-yoga");
+ const pubSub = createPubSub();
const resolvers = {
Mutation,
Query,
User,
Link
}
const schema = createSchema({
typeDefs: fs.readFileSync(path.join(__dirname, 'schema.graphql'), 'utf-8'),
resolvers: resolvers
})
const prisma = new PrismaClient();
// 基于graphql的scheme,创建一个graphql-yoga的实例
const yoga = createYoga({
schema,
context: ({ req }) => {
return {
...req,
prisma,
+ pubSub,
userId: req && req.headers.authorization
? getUserId(req)
: null
}
}
})
// 基于实例化后的yoga,创建一个server
const server = createServer(yoga)
// 启动server
server.listen(4000, () => {
console.info('Server is running on http://localhost:4000/graphql')
})
接下来,在src/server/resolvers文件夹中,新建Subscription.js文件,编写订阅逻辑:
function newLinkSubscribe(parent, args, context, info) {
// ①
return context.pubSub.subscribe("NEW_LINK")
}
const newLink = {
subscribe: newLinkSubscribe,
resolve: payload => {
// ②
return payload
},
}
module.exports = {
newLink,
}
在这里实现了一个订阅的方法,用挂载在上下文中的pubSub,来订阅NEW_LINK事件。
由于对于返回的数据没有任何处理,因此在②中直接返回了payload。
接着需要在src/server/resolvers/Mutation.js文件中,添加下面这一行,在创建链接完成后,推送这个信息:
async function post(parent, args, context) {
const { userId } = context;
const newLink = await context.prisma.link.create({
data: {
url: args.url,
description: args.description,
postedBy: { connect: { id: userId } },
}
});
+ context.pubSub.publish("NEW_LINK", newLink);
return newLink;
}
最后,需要再src/server/index.js文件中,添加Subscription引用即可:
//...
+ const Subscription = require('./resolvers/Subscription');
const {createPubSub} = require("graphql-yoga");
const pubSub = createPubSub();
const resolvers = {
Mutation,
Query,
User,
Link,
+ Subscription,
}
const schema = createSchema({
typeDefs: fs.readFileSync(path.join(__dirname, 'schema.graphql'), 'utf-8'),
resolvers: resolvers
})
//...
测试效果
打开http://localhost:4000/graphq页面,并在下面的位置,将自己的token粘贴进去:
接着输入下面的内容,创建链接:
请注意,先粘贴暂时不要执行
mutation {
post(url: "baidu.com", description: "百度一下") {
id
}
}
接下来再打开一个http://localhost:4000/graphq页面,将下面的内容粘贴进入,并且点击执行按钮。此时你将会看到一个一直在转圈的loading,证明正在实时监听数据。
subscription {
newLink {
id
url
description
postedBy {
id
name
email
}
}
}
接下来,执行第一个打开的页面添加链接,此时已经创建成功
这时你再打开第二个链接,就会发现,同样也返回了这个链接的结果,证明监听成功!
到这里就完成了所有的教程,原版教程中还有对链接进行按赞功能,由于本文都已经覆盖了这些操作的类似写法,因此笔者就没有在这个教程中讲述了,有兴趣的同学可以戳这里👉🏻www.howtographql.com/react-apoll… 来查看详细教程。
本教程的代码,你可以在github上下载并运行,如果发现有任何问题欢迎issue 仓库地址:github.com/zyc95/hacke…
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情