![](/img/trans.png)
[英]When Stitching using HotChocolate, How Can A Remote Schema's Type Be Renamed?
[英]`StringOperationFilterInput` was already registered by another type, when stitching a remote GraphQL schema in HotChocolate
我有一个主要的 GraphQL 项目,它服务于书籍,还有一个次要项目服务于电影,两者都包括过滤。 我想将辅助服务器的模式添加到主服务器,这样我就可以通过将查询转发到辅助服务器来查询电影。 我使用了模式拼接教程。
没有过滤效果很好(我可以跳到主服务器上的/graphql
并查询电影),但是将[UseFiltering]
添加到GetMovie
产生错误:
The name `StringOperationFilterInput` was already registered by another type. (HotChocolate.Data.Filters.StringOperationFilterInputType)
at HotChocolate.Configuration.TypeRegistry.Register(NameString typeName, RegisteredType registeredType)
显然,两种模式都生成用于过滤的类型,例如StringOperationFilterInput
,但模式拼接不想合并它们。 不知道我能在这里做什么。
最小示例:主项目Program.cs
:
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)
.AddTypeExtensionsFromFile("./Stitching.graphql")
.AddFiltering();
var app = builder.Build();
app.MapGraphQL();
app.Run();
public record Book(string Name);
public class Query
{
[UseFiltering] public IEnumerable<Book> GetBook() => new[] { new Book("A book") };
}
主要项目的Stitching.graphql
:
extend type Query {
movies: [Movie!]! @delegate(schema: "Movies", path:"movie")
}
二级项目Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseUrls("https://localhost:7001/");
builder.Services.AddGraphQLServer()
.AddQueryType<Query>()
.AddFiltering();
var app = builder.Build();
app.MapGraphQL();
app.Run();
public record Movie(string Name);
public class Query
{
[UseFiltering] public IEnumerable<Movie> GetMovie() => new[] { new Movie("Die Hard") };
}
我想到了。 首先,我们需要添加一个 TypeMergeHandler 来跳过已经注册的远程类型。 不幸的是,要跳过的重复类型必须进行硬编码,因为没有明显的方法来检查已经注册的类型。 我根据打印的错误消息 GraphQL 不断添加报告的重复类型。
builder.Services.AddTypeMergeHandler<GraphqlTypeMergeHandler>()
public class GraphqlTypeMergeHandler : ITypeMergeHandler
{
private readonly MergeTypeRuleDelegate _next;
private readonly string[] _duplicateTypes = new[]
{
"ComparableNullableOfDateTimeOperationFilterInput",
"ComparableNullableOfDecimalOperationFilterInput",
"ComparableNullableOfInt32OperationFilterInput",
"BooleanOperationFilterInput",
"StringOperationFilterInput",
"SortEnumType",
"PageInfo",
};
public GraphqlTypeMergeHandler(MergeTypeRuleDelegate next) => _next = next;
public void Merge(ISchemaMergeContext context, IReadOnlyList<ITypeInfo> types)
{
var typeName = types[0].Definition.Name.Value;
if (_duplicateTypes.Contains(typeName))
return;
_next(context, types);
}
}
其次,需要调整Stitching.graphql
以支持过滤,因为Movie
查询现在包含where
参数:
extend type Query {
movies(where: MovieFilterInput): [Movie!]!
@delegate(schema: "Movies", path:"movie(where: $arguments:where)")
}
最后,我示例中的Book
和Movie
类型是具有位置语法的记录,而 GraphQL 类型必须具有无参数构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.