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

HotChocolate 13:Schema First模式下Mutation无法正常工作

问题解决:HotChocolate 13 Schema First下Mutation Relay ID转换失败

问题根源

在Schema First模式下,SDL中定义的ID!类型默认会被映射为C#的string类型,而你在UpdatePostInput中用[ID(nameof(Post))]标记的int Id,框架并没有自动触发Relay ID(Base64编码格式)的解析逻辑——这和Code First模式不同,Code First会通过属性自动生成对应的类型配置;Query操作则是因为框架对Query参数的ID解析做了默认处理。

解决方案

方案一:通过输入类型绑定配置ID解析

创建自定义输入类型描述器,显式指定Id字段的Relay ID类型关联,触发自动解析:

  1. 定义输入类型配置类:
public class UpdatePostInputType : InputObjectType<UpdatePostInput>
{
    protected override void Configure(IInputObjectTypeDescriptor<UpdatePostInput> descriptor)
    {
        descriptor.Field(t => t.Id)
            .ID(nameof(Post)); // 关联Post类型,让框架自动解析Relay ID
    }
}
  1. 在GraphQL服务配置中绑定该类型:
builder.Services.AddGraphQLServer()
    .AddGlobalObjectIdentification()
    .AddMutationType()
    .BindRuntimeType<UpdatePostInput, UpdatePostInputType>(); // 绑定输入类型配置

方案二:手动解码Relay ID

如果不想创建额外的类型配置,可以在业务方法中手动解码ID,需先调整UpdatePostInput的Id类型为string:

  1. 修改UpdatePostInput定义:
public record UpdatePostInput(string Id,
                              string Title,
                              string Content,
                              List<PostTagInput> Tags);
  1. 在UpdatePostAsync方法中注入IIdSerializer解码ID:
[UseDbContext(typeof(ApiContext))]
public async Task<UpdatePostPayload> UpdatePostAsync(UpdatePostInput input,
                                                     [Service] ITopicEventSender eventSender,
                                                     [Service] IIdSerializer idSerializer,
                                                     CancellationToken cancellationToken,
                                                     ApiContext context)
{
    // 解码Relay ID为int类型
    var (_, postIdStr) = idSerializer.Deserialize(input.Id);
    if (!int.TryParse(postIdStr, out var postId))
    {
        // 处理ID解析失败的情况
        return new UpdatePostPayload { Errors = new List<ApiError> { new ApiError("Invalid post ID") } };
    }

    // 使用postId进行后续业务操作
    ...
}

方案三:全局配置输入ID转换器(谨慎使用)

如果多个输入类型都需要处理Relay ID到int的转换,可以配置全局类型转换器,但要注意可能影响其他ID字段的解析:

builder.Services.AddGraphQLServer()
    .AddGlobalObjectIdentification()
    .AddMutationType()
    .AddTypeConverter<string, int>((input, context) =>
    {
        var idSerializer = context.Services.GetRequiredService<IIdSerializer>();
        var (_, id) = idSerializer.Deserialize(input);
        return int.Parse(id);
    });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 14:02:09