You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hot Chocolate GraphQL合并Pokemon与图片服务报错求助

问题分析
  1. 报错原因:@delegate指令中使用了$fields:id,但pokemonTest查询未定义id参数或关联的字段来源,导致系统无法找到id字段。
  2. 核心需求:将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:04:56