Skip to content

Argument definitions and input field definitions use same class #395

@Shane32

Description

@Shane32

Argument definitions (children of GraphQLArgumentsDefinition) and fields of input object type definitions (children of GraphQLInputFieldsDefinition) use the same class type of GraphQLInputValueDefinition. This means that it is not possible to determine the directive location from the type alone; you'd need the parent also.

Example code:

private static DirectiveLocation GetDirectiveLocation(ASTNode node, ASTNode parentNode) => node switch
{
    // type definitions
    GraphQLSchemaDefinition => DirectiveLocation.Schema,
    GraphQLScalarTypeDefinition => DirectiveLocation.Scalar,
    GraphQLObjectTypeDefinition => DirectiveLocation.Object,
    GraphQLFieldDefinition => DirectiveLocation.FieldDefinition,
    GraphQLInputValueDefinition when parentNode is GraphQLArgumentsDefinition => DirectiveLocation.ArgumentDefinition,
    GraphQLInterfaceTypeDefinition => DirectiveLocation.Interface,
    GraphQLUnionTypeDefinition => DirectiveLocation.Union,
    GraphQLEnumTypeDefinition => DirectiveLocation.Enum,
    GraphQLEnumValueDefinition => DirectiveLocation.EnumValue,
    GraphQLInputObjectTypeDefinition => DirectiveLocation.InputObject,
    GraphQLInputValueDefinition when parentNode is GraphQLInputFieldsDefinition => DirectiveLocation.InputFieldDefinition,

    // executable definitions
    GraphQLOperationDefinition opDef when opDef.Operation == OperationType.Query => DirectiveLocation.Query,
    GraphQLOperationDefinition opDef when opDef.Operation == OperationType.Mutation => DirectiveLocation.Mutation,
    GraphQLOperationDefinition opDef when opDef.Operation == OperationType.Subscription => DirectiveLocation.Subscription,
    GraphQLField => DirectiveLocation.Field,
    GraphQLFragmentDefinition => DirectiveLocation.FragmentDefinition,
    GraphQLFragmentSpread => DirectiveLocation.FragmentSpread,
    GraphQLInlineFragment => DirectiveLocation.InlineFragment,
    GraphQLVariableDefinition => DirectiveLocation.VariableDefinition,

    _ => throw new ArgumentOutOfRangeException(nameof(node))
};

To make it easier, a DirectiveLocation property should be added to IHasDirectivesNode.

The code snippet above is non-breaking and could be added as an extension method, but the fact that the parent is required severely limits its usefulness. I suggest a breaking change to address this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions