如何用type-graphql与aws-lambda-graphql实现GraphQL订阅?订阅遇阻求助
我帮你排查一下这段订阅代码里的几个关键问题,这些大概率是导致功能失效的原因:
1. PubSub实例未正确注入到Resolver Context
你在Resolver外部创建了pubSub实例,但订阅代码里用了context.pubSub——如果在构建GraphQL Schema/服务器时,没有把这个实例注入到请求上下文(Context)里,context.pubSub会是undefined,自然无法正常订阅。
解决方法是在构建Schema时,把pubSub注入到Context中:
// 假设你用TypeGraphQL的buildSchema方法 const schema = await buildSchema({ resolvers: [YourNotificationResolver], context: () => ({ pubSub }), // 将pubSub实例传入上下文 });
2. Subscribe函数的写法错误
TypeGraphQL的subscribe配置项需要返回一个AsyncIterator,但你当前的写法context.pubSub.subscribe('NEW_MESSAGE')(rootValue.message)完全不符合规范:
subscribe('NEW_MESSAGE')本身就会返回订阅的异步迭代器,不需要额外传rootValue.message参数rootValue在订阅的subscribe阶段还没有有效数据,它是在发布事件后才会传递给resolve函数的
修正后的订阅配置应该是:
@Subscription({ subscribe: (_root, _args, context) => context.pubSub.subscribe('NEW_MESSAGE') }) normalSubs(@Root() payload: NotificationPayload): Notification { return { id: payload.id, message: payload.message, date: new Date() }; }
3. 确认事件发布逻辑是否存在且正确
订阅功能依赖事件发布才能触发——你只贴了订阅代码,要确保代码里存在对应的发布逻辑,比如一个Mutation来触发消息发布:
@Mutation(() => Boolean) async publishNotification(@Arg("message") message: string): Promise<boolean> { await pubSub.publish('NEW_MESSAGE', { id: Date.now().toString(), // 生成唯一ID message }); return true; }
而且发布的Payload结构必须和NotificationPayload完全匹配,否则resolve阶段拿不到正确的数据。
4. DynamoDBEventStore的配置验证
因为你用了aws-lambda-graphql的DynamoDBEventStore,还需要确认:
- 对应的DynamoDB表(默认表名是
graphql-subscriptions)已经创建,如果自定义了表名,要在DynamoDBEventStore配置里指定tableName参数 - 运行代码的环境(本地/Lambda等)拥有足够的DynamoDB权限(比如
dynamodb:PutItem、dynamodb:GetItem、dynamodb:Scan) awsClient的区域、凭证配置正确,能正常连接到DynamoDB服务
修复后的完整示例代码
把上述问题修正后,完整的Resolver代码大概是这样:
import { Subscription, Root, Resolver, Mutation, Arg, buildSchema } from 'type-graphql'; import { DynamoDBEventStore, PubSub } from 'aws-lambda-graphql'; import { awsClient } from '../../config/database'; import { Notification, NotificationPayload } from './notification.type'; const eventStore = new DynamoDBEventStore({ dynamoDbClient: awsClient, // tableName: 'your-custom-table-name' // 如果用了自定义表名,取消注释 }); const pubSub = new PubSub({ eventStore }); @Resolver() export class NotificationResolver { @Subscription({ subscribe: (_root, _args, context) => context.pubSub.subscribe('NEW_MESSAGE') }) normalSubs(@Root() payload: NotificationPayload): Notification { return { id: payload.id, message: payload.message, date: new Date() }; } @Mutation(() => Boolean) async sendNotification(@Arg("message") message: string): Promise<boolean> { await pubSub.publish('NEW_MESSAGE', { id: Date.now().toString(), message }); return true; } } // 构建Schema时注入Context const schema = await buildSchema({ resolvers: [NotificationResolver], context: () => ({ pubSub }), });
内容的提问来源于stack exchange,提问作者Thompho Madula
相关产品推荐
相关产品推荐

