Hot Chocolate GraphQL合并Pokemon与图片服务报错求助
问题分析
- 报错原因:
@delegate指令中使用了$fields:id,但pokemonTest查询未定义id参数或关联的字段来源,导致系统无法找到id字段。 - 核心需求:将Pokemon服务的
PokemonModel与图片服务的PokemonImage数据合并为一个统一类型,同时处理两者id类型不一致(Int vs String)的问题。
解决方案
方案1:扩展现有PokemonModel类型(推荐)
直接扩展Pokemon服务返回的PokemonModel,添加图片服务的url字段,无需创建新类型,实现更简洁。
修改Stitching.graphql
# 扩展PokemonModel,新增url字段,从图片服务获取对应数据 extend type PokemonModel { url: String! @delegate( schema: "PokemonImage" # 将PokemonModel的Int类型id转为String,传递给图片服务的pokemonImageById查询 path: "pokemonImageById(id: $fields:id.toString()).url" ) } # 扩展根Query,可直接复用Pokemon服务的pokemon查询(已自动包含新增的url字段) extend type Query { # 可选:新增根据id获取单个整合后Pokemon的查询 pokemonById(id: Int!): PokemonModel! @delegate( schema: "Pokemon" path: "pokemon(filter: {id: $args:id})[0]" ) }
修改C#服务配置
无需额外调整,保留原有配置即可:
const string Pokemon = "Pokemon"; const string PokemonImage = "PokemonImage"; // 配置两个远程服务的HttpClient builder.Services.AddHttpClient(Pokemon, c => c.BaseAddress = new Uri("http://localhost:7071/api/graphql")); builder.Services.AddHttpClient(PokemonImage, c => c.BaseAddress = new Uri("http://localhost:7074/api/graphql")); builder .AddGraphQLFunction() .AddRemoteSchema(Pokemon, ignoreRootTypes: true) .AddRemoteSchema(PokemonImage, ignoreRootTypes: true) .AddTypeExtensionsFromString("type Query { }") // 定义基础Query类型用于扩展 .AddTypeExtensionsFromFile("Stitching.graphql");
方案2:创建独立的PokemonMasterDTO类型
如果需要完全独立的新类型,可使用@merge指令合并两个服务的数据:
修改Stitching.graphql
# 定义整合后的类型,包含两个服务的所有字段 type PokemonMasterDTO { # Pokemon服务的字段 id: Int! pokemon: String! species_id: Int! height: Float! weight: Float! base_experience: Int! type_1: String! type_2: String! hp: Int! attack: Int! defense: Int! special_attack: Int! special_defense: Int! speed: Int! color_1: String! color_2: String! color_f: String! egg_group_1: String! egg_group_2: String! url_icon: String! generation_id: Int! url_image: String! # 图片服务的字段 url: String! } extend type Query { # 根据id获取单个整合后的Pokemon pokemonMaster(id: Int!): PokemonMasterDTO! @merge( delegates: [ # 从Pokemon服务获取基础数据 { schema: "Pokemon", path: "pokemon(filter: {id: $args:id})[0]" }, # 从图片服务获取图片url,转换id类型 { schema: "PokemonImage", path: "pokemonImageById(id: $args:id.toString())" } ] ) # 获取所有整合后的Pokemon列表 pokemonMasters: [PokemonMasterDTO!]! @merge( delegates: [ { schema: "Pokemon", path: "pokemon" }, { schema: "PokemonImage", path: "pokemonImage" } ] # 根据id字段匹配两个服务的数据,指定id参数名称 keyField: "id" keyArg: "id" ) }
C#配置与方案1一致
关键说明
$args:xxx:引用当前查询的参数值$fields:xxx:引用当前类型的字段值.toString():Hot Chocolate内置的类型转换方法,解决Int与String类型不匹配问题@delegate:将字段查询委托到指定远程服务@merge:将多个远程服务的查询结果合并为单个类型,需指定匹配的key字段
内容的提问来源于stack exchange,提问作者kolek
相关产品推荐
相关产品推荐

