Директивы Graphql не работают для входных аргументов мутации при передаче аргументов в качестве внешних переменных

#graphql #arguments #apollo-server #mutation

#graphql #аргументы #apollo-сервер #мутация

Вопрос:

Я реализую пользовательские директивы Graphql для проверки ввода данных клиентом. Пример кода, приведенный ниже, я ссылался на официальные примеры здесь: https://www.apollographql.com/docs/apollo-server/schema/creating-directives/#enforcing-value-restrictions

 const { ApolloServer, gql, SchemaDirectiveVisitor } = require('apollo-server');
const { GraphQLScalarType, GraphQLNonNull } = require('graphql');

const typeDefs = gql`
  directive @validateInput on FIELD_DEFINITION | INPUT_FIELD_DEFINITION | ARGUMENT_DEFINITION

type Mutation {
 sampleMutation(
    test1: String @validateInput
    nestedInput: SampleMutationInput
  ): String
}

input SampleMutationInput {
  test2: String @validateInput
}
`;
 

Реализация логики директивы:

 class ValidateInputDirective extends SchemaDirectiveVisitor {
  visitInputFieldDefinition(field) {
    this.wrapType(field);
  }

  visitFieldDefinition(field) {
    this.wrapType(field);
  }

  visitArgumentDefinition(argument) {
    console.log('visitArgumentDefinition', argument);
    this.wrapType(argument);
  }

  wrapType(field) {
    console.log('wrapType', field);
    if (
      field.type instanceof GraphQLNonNull amp;amp;
      field.type.ofType instanceof GraphQLScalarType
    ) {
      field.type = new GraphQLNonNull(
        new ValidateInputType(field.type.ofType)
      );
    } else if (field.type instanceof GraphQLScalarType) {
      field.type = new ValidateInputType(field.type);
    } else {
      throw new Error(`Not a scalar type: ${field.type}`);
    }
  }
}

class ValidateInputType extends GraphQLScalarType {
  constructor(type) {
    super({
      name: 'ValidatedInput',
      serialize(value) {
        return value;
      },
      parseValue(value) {
        const result = type.parseValue(value);
        
        if (/[?!]/.test(result)) {
          throw new Error('Invalid characters');
        }
        return resu<
      },
      parseLiteral(ast) {
        const result = type.parseLiteral(ast);
        
        if (/[?!]/.test(result)) {
          throw new Error('Invalid characters');
        }
        return resu<
      },
    });
  }
}

export default { validateInput: ValidateInputDirective };
 

Это работает, как и ожидалось, для поля ввода ‘test2’, но для аргумента ‘test1’ это работает, когда строковое значение напрямую передается мутации, затем вызывается метод «parseLiteral» и к входному значению применяется логика проверки. Однако, когда я передаю значение ‘test1’ в качестве внешних переменных (через формат JSON), директива не работает, и метод «parserValue» никогда не вызывается.

Что я нашел до сих пор:

  1. «parserValue» используется, когда входные данные поступают из переменной JSON. «parseLiteral» используется, когда входные данные поступают непосредственно из запроса / мутации.
  2. Похоже, ошибка в инструментах Graphql в соответствии с https://github.com/ardatan/graphql-tools/issues/789

Я хочу понять:

  1. в чем реальная разница между аргументом, передаваемым переменной, и прямым переходом к мутации?
  2. есть ли альтернативный способ применить директивы к аргументу, чтобы избежать этой проблемы?
  3. Если это действительно ошибка с Graphql, исправлена ли она сейчас? Какую версию я должен использовать для решения проблемы?