新闻详情

新闻详情

首页 / 资讯中心 / 详情

TypeGraphQL 订阅(Subscriptions)实战指南:从 @Subscription 装饰器到自定义 PubSub 系统

发布时间:2026/9/28 20:37:17来源:尧图网络
TypeGraphQL 订阅(Subscriptions)实战指南:从 @Subscription 装饰器到自定义 PubSub 系统
后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载TypeGraphQL 基于类与装饰器构建 GraphQL schema除了常规的 Query 与 Mutation 外还内置了对 GraphQL 第三种操作类型——订阅Subscription的完整支持。本文以官方 v0.17.4 文档为核心结合当前仓库中的 Subscription 装饰器实现、PubSub 接口定义 以及 simple-subscriptions 示例 与 redis-subscriptions 示例系统讲解订阅的创建、主题触发、过滤、自定义 PubSub 以及订阅服务器的搭建帮助你掌握一套可落地的实时推送方案。为什么需要订阅GraphQL 的第三种操作GraphQL 用 Query 完成读取、用 Mutation 完成写入。但在大量真实场景中客户端还希望当服务端数据发生变化时能主动收到推送而不是反复轮询。订阅Subscription正是为此而生客户端与服务端之间建立一条长期连接服务端在数据变更时把更新推送给相关客户端。TypeGraphQL 对订阅提供了开箱即用的支持。在 v0.17.4 版本中它基于 Apollo 出品的graphql-subscriptions包订阅的核心机制是一个pubsub发布/订阅系统——发布方把事件与载荷payload发送到某个主题topic订阅方监听该主题并收到回调。仓库中的PubSub接口 明确定义了这个协议publish(routingKey, ...args)负责发布subscribe(routingKey, dynamicId?)返回一个AsyncIterable。创建订阅Subscription() 装饰器订阅解析器与 Query/Mutation 解析器 类似但稍复杂。首先像往常一样定义一个普通类方法用Subscription()装饰器标注class SampleResolver { // ... Subscription() newNotification(): Notification { // ... } }从源码看Subscription.ts 会收集订阅处理器元数据其中包含topics、topicId、filter、subscribe等选项并抛出MissingSubscriptionTopicsError当topics是空数组时。指定订阅主题topics必须提供要订阅的主题支持三种形式也可以使用 TypeScript 枚举增强类型安全class SampleResolver { // ... Subscription({ topics: NOTIFICATIONS, // 单个主题字符串 topics: [NOTIFICATIONS, ERRORS], // 或者主题数组 topics: ({ args, payload, context }) args.topic, // 或根据订阅参数动态生成主题的函数 }) newNotification(): Notification { // ... } }动态主题函数接收{ args, payload, context }可根据订阅时传入的参数如args.topic决定监听哪个主题。该模式在示例中也有体现notification.resolver.ts 的subscribeToTopicFromArg用topics: ({ args }) args.topic实现动态订阅。用 filter 过滤事件filter选项决定哪些主题事件触发订阅函数应返回boolean或Promisebooleanclass SampleResolver { // ... Subscription({ topics: NOTIFICATIONS, filter: ({ payload, args }) args.priorities.includes(payload.priority), }) newNotification(): Notification { // ... } }示例仓库中notification.resolver.ts 的subscriptionWithFilter用payload.id % 2 0过滤偶数 ID 的通知subscriptionWithMultipleTopics则展示了监听多个主题并同样过滤的用法。自定义 subscribe 逻辑subscribe选项允许自定义订阅逻辑例如接入 Prisma 的订阅功能。它应是一个返回AsyncIterator的函数class SampleResolver { // ... Subscription({ subscribe: ({ args, context }) { return context.prisma.$subscribe.users({ mutation_in: [args.mutationType] }); }, }) newNotification(): Notification { // ... } }注意subscribe选项不能与topics、filter混用。如果仍需过滤可以使用graphql-subscriptions包提供的withFilter函数。用 Root() 接收载荷并转换返回形状订阅解析器通过Root()接收来自 pubsub 主题的载荷并可将其转换为返回形状class SampleResolver { // ... Subscription({ topics: NOTIFICATIONS, filter: ({ payload, args }) args.priorities.includes(payload.priority), }) newNotification( Root() notificationPayload: NotificationPayload, Args() args: NewNotificationsArgs, ): Notification { return { ...notificationPayload, date: new Date(), }; } }示例中 notification.resolver.ts 的normalSubscription即从Root()解构出id、message再拼装成带date的Notification返回recipe.resolver.ts 也展示了从Root()载荷重建Comment类型的过程。触发订阅主题PubSub() 注入发布器创建了订阅后关键在于如何触发主题。主题可由数据库等外部源触发也常在 Mutation 中触发——比如修改了客户端关心的资源时。假设有这样一个新增评论的 Mutationclass SampleResolver { // ... Mutation(returns Boolean) async addNewComment(Arg(comment) input: CommentInput) { const comment this.commentsService.createNew(input); await this.commentsRepository.save(comment); return true; } }使用PubSub()装饰器把pubsub注入方法参数即可触发主题并向所有订阅者发送载荷class SampleResolver { // ... Mutation(returns Boolean) async addNewComment(Arg(comment) input: CommentInput, PubSub() pubSub: PubSubEngine) { const comment this.commentsService.createNew(input); await this.commentsRepository.save(comment); // 在这里触发订阅主题 const payload: NotificationPayload { message: input.content }; await pubSub.publish(NOTIFICATIONS, payload); return true; } }为了便于测试mock/stub还可以只注入绑定到指定主题的publish方法使用PubSub(TOPIC_NAME)装饰器配合PublisherTPayload类型class SampleResolver { // ... Mutation(returns Boolean) async addNewComment( Arg(comment) input: CommentInput, PubSub(NOTIFICATIONS) publish: PublisherNotificationPayload, ) { const comment this.commentsService.createNew(input); await this.commentsRepository.save(comment); // 触发订阅主题 await publish({ message: input.content }); return true; } }这样所有挂在NOTIFICATIONS主题上的订阅在addNewCommentMutation 执行时都会被触发。在仓库示例中recipe.resolver.ts 的addNewComment正是先保存评论再通过pubSub.publish(Topic.NEW_COMMENT, {...})发布新评论载荷。使用自定义 PubSub 系统面向生产环境的扩展默认情况下TypeGraphQL 使用graphql-subscriptions中基于 EventEmitter 的简单PubSub。它有一个明显缺陷仅在单个 Node.js 进程实例下才正确工作。为了更好的可扩展性应使用外部存储如 Redis支撑的 PubSub 实现例如graphql-redis-subscriptions包。只需按包文档创建 PubSub 实例再传入buildSchema选项const myRedisPubSub getConfiguredRedisPubSub(); const schema await buildSchema({ resolvers: [__dirname /**/*.resolver.ts], pubSub: myRedisPubSub, });当前仓库的 redis-subscriptions 示例 展示了生产级做法通过createPubSub搭配graphql-yoga/redis-event-target创建基于 Redis 的分布式 pubsub并使用ioredis的retryStrategy配置重连策略index.ts 中通过buildSchema({ resolvers: [RecipeResolver], pubSub })注入该实例。需要说明的是v0.17.4 文档以graphql-redis-subscriptions为例当前仓库示例采用的是 Yoga 生态的 Redis 事件目标实现——两者都遵循publish/subscribe协议且启动 Redis 示例前必须有运行中的 Redis 实例并可能需要按环境变量如REDIS_URL调整连接参数。创建订阅服务器WebSocket 传输层引导指南 及之前的示例都使用apollo-server为 GraphQL API 创建 HTTP 端点。要启用订阅无需手动实现不受 HTTP 约束、可做推送式通信WebSocket的传输层——apollo-server内置了基于 WebSocket 的订阅支持开箱即用无需改动引导配置。当然如果需要也可以显式提供subscriptions配置// 创建 GraphQL 服务器 const server new ApolloServer({ schema, subscriptions: { path: /subscriptions, // 其他选项与钩子如 onConnect }, });完成现在在/subscriptions路径下我们同时拥有了 GraphQL 订阅服务器和普通 HTTP GraphQL 服务器。仓库的 simple-subscriptions/index.ts 展示了当前版本更主流的做法用graphql-yoga的createYoga({ schema })创建支持订阅的服务器再交给 Node 原生http模块监听 4000 端口。示例与进一步阅读查看订阅如何工作的 simple-subscriptions 示例包含普通订阅、过滤订阅、多主题订阅、动态主题、动态主题 ID 等完整演示其生成的 schema.graphql 中可看到type Subscription对应的字段定义。生产环境建议使用更可扩展的 Redis 型 pubsub 系统参考 redis-subscriptions 示例。注意启动该示例需要运行中的 Redis 实例并可能需修改代码提供连接参数示例通过REDIS_URL环境变量读取。相关 API 细节可继续阅读 Subscription 装饰器源码、PubSub 接口 与 subscriptions 测试。从创建订阅、过滤事件、触发主题到更换可扩展的 Redis pubsub 与搭建支持 WebSocket 的订阅服务器本文覆盖了 TypeGraphQL 订阅的完整链路。接下来你可以在自己的解析器中按需组合这些能力构建出稳健的实时数据推送功能。赞分享后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载相关推荐OBS多路RTMP推流插件深度解析与实践指南OBS多路RTMP推流插件深度解析与实践指南 在当今多平台直播成为主流的背景下内容创作者面临着同时向多个平台推送直播流的复杂需求。传统的单路推流方式不仅效率低后端GraphQLAPI设计TypeGraphQL 订阅Subscriptions完全指南从 Subscription 装饰器到生产级 PubSub 架构TypeGraphQL 订阅Subscriptions完全指南从 Subscription 装饰器到生产级 PubSub 架构 导读 本文以 Type后端GraphQLAPI设计TypeGraphQL 订阅Subscriptions完整实战指南从装饰器到自定义 PubSub 与 WebSocket 服务端TypeGraphQL 订阅Subscriptions完整实战指南从装饰器到自定义 PubSub 与 WebSocket 服务端 TypeGraphQL后端GraphQLAPI设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

汇川PLC跑马灯5种实现方案:定时器精度与IO映射实战指南 2026/9/28 22:20:07

汇川PLC跑马灯5种实现方案:定时器精度与IO映射实战指南

1. 项目概述:为什么一个跑马灯程序值得花三天时间反复推敲?汇川PLC跑马灯程序,听起来像教科书第一章的入门练习——接几个LED灯,写几行梯形图,用个TON定时器循环移位,十分钟搞定。但如果你真在产线上调试过…

阅读更多 →
工业4-20mA电流环设计:XTR115两线制电路原理、参数计算与调试避坑指南 2026/9/28 22:20:00

工业4-20mA电流环设计:XTR115两线制电路原理、参数计算与调试避坑指南

1. 工业现场为什么还在用4-20mA电流环在车间里干过几年的人都会发现一个有意思的现象:现场变送器、压力传感器、温度变送器,甚至一些阀门定位器,信号线拉出去几百米甚至上千米,用的还是那对看起来"老掉牙"的4-20mA电流环…

阅读更多 →
Agent-Native架构实战:从AI Agent到工具调用与智能体原生应用 2026/9/28 22:20:00

Agent-Native架构实战:从AI Agent到工具调用与智能体原生应用

1. agent-native到底是什么:一次把“Agent当主角”的架构重构前几个月我一直在做一个内部知识系统的改造,刚开始团队统一口径都叫“AI助手”,结果做着做着大家发现不对劲——我们给系统加了一个又一个聊天入口,用户问一句答一句&a…

阅读更多 →
MTK6765 LCD花屏五步定位法:从MIPI信号到DRM寄存器 2026/9/28 22:20:00

MTK6765 LCD花屏五步定位法:从MIPI信号到DRM寄存器

1. 花屏不是玄学,是信号链路上5个确定性故障点的叠加刚接手MTK6765平台LCD调试时,我盯着那块疯狂滚动、色块撕裂、边缘错位的屏幕,第一反应不是查手册,而是掏出示波器探头——因为花屏从来不是“驱动没写对”这种模糊结论&#xf…

阅读更多 →
Agent-Native架构实战:从AI集成到智能体原生应用设计 2026/9/28 22:19:53

Agent-Native架构实战:从AI集成到智能体原生应用设计

1. 从"AI能力"到"智能体原生"的思维转变这两年做AI应用开发,我见过太多团队把大模型接进现有系统后,发现效果远不如预期。一个常见的尴尬场景是:老板说"接入AI提升效率",开发同学花两周时间调好接口…

阅读更多 →
Harness SDK实战:多智能体工作流编排与DeepSeek集成指南 2026/9/28 22:19:32

Harness SDK实战:多智能体工作流编排与DeepSeek集成指南

1. 内容整体设计与核心思路拆解1.1 项目背景:为什么需要Harness SDK我最初接触到harness-sdk这个项目,是因为在搭建AI智能体工作流时遇到了一个非常现实的问题:单独调用各个大模型的接口并不难,难的是如何把多个智能体、多个工具、…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉