HotChocolate GraphQL: 如何在整个架构中将类型设置为可为null

huangapple go评论61阅读模式
英文:

HotChocolate GraphQL: how to set a type as nullable for the whole schema

问题

因为我们的业务模型,我们有一个名为"wrapper"的类型,它实现为一个结构体。这个类型可以容纳一些数据,或者是"空的"。当结构体包含数据时,我们希望将其发送为一个字符串,但当它是空的时,字段的值应为null。这很容易实现(只需定义一个新的标量类型),但当值为null时,HotChocolate会抛出异常,因为具有结构体类型的字段不能为null。

我不想为结构体的每个实例添加注释,因此我正在寻找一种在发现模式时修改模式的通用方法。看起来使用TypeInterceptor是正确的方法,但API的那部分文档几乎没有内容。

有什么想法吗?

英文:

Because of our business model we have a "wrapper" type that is implemented as a struct. The type can either hold some data or be "empty". When the struct holds some data, we want to send it as a string but when it is empty the value of the field should be null. This is pretty easy to do (just define a new scalar type) but when the value is null HotChocolate throws an exception because a field that has a struct as the type cannot be null.

I don't want to annotate every instance of the struct so I am looking at a generic way to modify the schema while it is being discovered. It seems that using a TypeInterceptor is the right thing to do but the documentation of that part of the API is almost non-existent.

Any idea?

答案1

得分: 1

是的,这是正确的。您可以使用类型拦截器来重写模式。覆盖 OnBeforeRegisterDependencies 方法。在那里,您可以访问字段和定义。

然后,您可以重写类型的可空性。

类似以下内容可能会起作用:

public class MakeTypeNullableInterceptor<T> : TypeInterceptor
{
    public override void OnBeforeRegisterDependencies(
        ITypeDiscoveryContext discoveryContext,
        DefinitionBase? definition,
        IDictionary<string, object?> contextData)
    {
        if (definition is ObjectTypeDefinition { Fields: var fields })
        {
            foreach (var field in fields)
            {
                if (field.Type is not ExtendedTypeReference { Type: var extendedType } typeRef)
                {
                    continue;
                }

                int position;
                for (position = 0; extendedType.ElementType is { } elementType; position++)
                {
                    extendedType = elementType;
                }

                if (extendedType.Source == typeof(T) && !extendedType.IsNullable)
                {
                    var typeInspector = discoveryContext.TypeInspector;

                    var nullability = typeInspector.CollectNullability(typeRef.Type);

                    nullability[position] = true;

                    field.Type = typeRef
                        .WithType(typeInspector.ChangeNullability(typeRef.Type, nullability));
                }
            }
        }
    }
}
英文:

Yes this is correct. You can use a type interceptor to rewrite the schema. Override the method OnBeforeRegisterDependencies. There you have access to the field and the definitions.

You can then rewrite the nullability of the type.

Something like this could work:

public class MakeTypeNullableInterceptor<T> : TypeInterceptor
{
    public override void OnBeforeRegisterDependencies(
        ITypeDiscoveryContext discoveryContext,
        DefinitionBase? definition,
        IDictionary<string, object?> contextData)
    {
        if (definition is ObjectTypeDefinition { Fields: var fields })
        {
            foreach (var field in fields)
            {
                if (field.Type is not ExtendedTypeReference { Type: var extendedType } typeRef)
                {
                    continue;
                }

                int position;
                for (position = 0; extendedType.ElementType is { } elementType; position++)
                {
                    extendedType = elementType;
                }

                if (extendedType.Source == typeof(T) && !extendedType.IsNullable)
                {
                    var typeInspector = discoveryContext.TypeInspector;

                    var nullability = typeInspector.CollectNullability(typeRef.Type);

                    nullability[position] = true;

                    field.Type = typeRef
                        .WithType(typeInspector.ChangeNullability(typeRef.Type, nullability));
                }
            }
        }
    }
}

huangapple
  • 本文由 发表于 2023年2月8日 16:40:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383153.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定