NestJS GraphQL Federation 2:@ResolveReference跨服务调用无响应求助
问题排查与修复方案
针对你遇到的@ResolveReference未触发的问题,从以下几个关键点排查:
1. 确认__typename与GraphQL schema一致
你在away_sport_team的@ResolveField中返回的__typename使用了SportTeamDto.name,这可能与GraphQL schema中实际生成的typename不匹配。
修复:
- 在
SportTeamDto上显式指定typename:
@ObjectType('SportTeam') // 显式定义GraphQL中的typename @Directive('@key(fields: "id")') @Directive('@shareable') export class SportTeamDto extends BaseDto { // ... 字段保持不变 }
- 在
HelloEventResolver的away_sport_team方法中,返回正确的__typename:
@ResolveField((of) => SportTeamDto) async away_sport_team(@Parent() data: HelloEventDto) { console.log('RESOLVE FIELD away_team FOR', data); return { __typename: 'SportTeam', // 与上面指定的typename一致 id: data.scheduled_event.sport_event.away_sport_team_id, }; }
2. 确保查询包含SportTeam的非ID字段
Apollo Gateway只有在请求了超出已提供字段(比如id)的其他字段时,才会触发@ResolveReference。如果你的查询只请求away_sport_team { id },网关不会调用sport-service。
示例正确查询:
query { helloScheduledEvent(data: { id: "your-event-id" }) { scheduled_event_id away_sport_team { id name # 必须请求非ID字段才会触发ResolveReference logo } } }
3. 检查sport-service的联邦配置
确保sport-service的GraphQL模块启用了Federation 2:
@Module({ imports: [ GraphQLModule.forRoot<ApolloDriverConfig>({ driver: ApolloDriver, autoSchemaFile: true, federation: { version: 2, // 明确指定联邦版本 }, }), ], providers: [SportTeamResolver, SportTeamService], }) export class SportModule {}
4. 显式指定@ResolveReference的返回类型
虽然NestJS会自动推断,但显式指定返回类型可以避免类型推断问题:
@ResolveReference(() => SportTeamDto) resolveReference(reference: { __typename: string; id: string }) { console.log('ResolveReference SportTeamDto', reference); return this.sportTeamService.get({ id: reference.id }); }
5. 验证网关的子服务配置
确认网关的ApolloGateway配置中包含sport-service的正确地址,且服务已正常启动:
@Module({ imports: [ GraphQLModule.forRoot<ApolloGatewayDriverConfig>({ driver: ApolloGatewayDriver, gateway: { supergraphSdl: new IntrospectAndCompose({ subgraphs: [ { name: 'scheduled-event', url: 'http://localhost:3001/graphql' }, { name: 'sport', url: 'http://localhost:3002/graphql' }, // 确保地址正确 ], }), }, }), ], }) export class GatewayModule {}
按以上步骤逐一排查,应该能解决@ResolveReference未触发的问题。
内容的提问来源于stack exchange,提问作者Axel Carisey
相关产品推荐
相关产品推荐

