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

HotChocolate Schema Stitching时过滤输入类型重复注册求助

解决HotChocolate Schema Stitching中过滤类型重复注册的问题

问题根源

主、次级服务各自启用了AddFiltering(),都会生成StringOperationFilterInput这类通用过滤输入类型,Schema合并时因为类型名称完全重复,导致注册冲突报错。


方案一:合并同名过滤类型(推荐)

利用HotChocolate的Schema合并能力,对两个Schema中结构完全一致的同名过滤类型进行合并,既保留两边的过滤功能,又避免冲突。

修改主项目的Program.cs,在添加远程Schema时配置类型合并规则:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpClient("Movies", c => c.BaseAddress = new Uri("https://localhost:7001/graphql"));
builder.Services.AddGraphQLServer()
    .AddQueryType<Query>()
    .AddRemoteSchema("Movies", ignoreRootTypes: true, configure: schema =>
    {
        schema.TypeMergeHandler((leftType, rightType) =>
        {
            // 匹配所有过滤操作输入类型,合并同名且结构一致的类型
            if (leftType.Name.EndsWith("OperationFilterInput") && 
                leftType.Name == rightType.Name &&
                leftType.Kind == TypeKind.InputObject &&
                rightType.Kind == TypeKind.InputObject)
            {
                return TypeMerge.Merge(leftType, rightType);
            }
            return TypeMerge.KeepLeft;
        });
    })
    .AddTypeExtensionsFromFile("./Stitching.graphql")
    .AddFiltering();

var app = builder.Build();
app.MapGraphQL();
app.Run();

方案二:为次级服务的过滤类型加前缀

给次级服务生成的过滤输入类型添加专属前缀,让它和主服务的类型名称区分开。

修改次级项目的Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseUrls("https://localhost:7001/");
builder.Services.AddGraphQLServer()
    .AddQueryType<Query>()
    .AddFiltering(options =>
    {
        // 为过滤类型添加"Movie"前缀
        options.AddConvention<IFilterConvention>(new FilterConvention
        {
            OperationName = typeName => $"Movie{typeName}"
        });
    });

var app = builder.Build();
app.MapGraphQL();
app.Run();

此时次级服务的过滤类型会变成MovieStringOperationFilterInput,和主服务的StringOperationFilterInput不再重名。如果需要在主服务端使用次级服务的过滤能力,需确保查询参数能正确映射到次级服务的类型。


方案三:主服务统一处理过滤

如果次级服务的数据量不大,可让主服务接管所有过滤逻辑,次级服务仅返回原始数据。

  1. 修改次级项目的Query类,移除[UseFiltering]特性:
public class Query
{
    public IEnumerable<Movie> GetMovie() => new[] { new Movie("Die Hard") };
}
  1. 修改次级项目的服务配置,移除AddFiltering():
builder.Services.AddGraphQLServer()
    .AddQueryType<Query>();
  1. 修改主项目的Stitching.graphql,给movies字段添加@useFiltering,由主服务本地处理过滤:
extend type Query {
  movies: [Movie!]! @delegate(schema: "Movies", path:"movie") @useFiltering
}

这种方式适合小数据量场景,主服务会先拉取所有Movies数据,再在本地应用过滤规则。


内容的提问来源于stack exchange,提问作者Orion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:45:47