Как получить тип поля в директиве схемы GraphQL (Node.js, graphql-tools)

Я использую директиву схемы, которая реализует visitFieldDefinition функция SchemaDirectiveVisitor, Я хочу знать тип поля, определенного в схеме и, например, если тип является массивом.

В схеме:

type DisplayProperties {
  description: StringProperty @property
  descriptions: [StringProperty]! @property
}

Директива о недвижимости:

class PropertyDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field) {
    // how to check that field type is StringProperty?

    // how to find out that the field type is an array?
  }
}

Использование сервера Apollo и graphql-tools.

2 ответа

Решение

Первый параметр передан visitFieldDefinition это GraphQLField объект:

interface GraphQLField<TSource, TContext, TArgs = { [key: string]: any }> {
    name: string;
    description: Maybe<string>;
    type: GraphQLOutputType;
    args: GraphQLArgument[];
    resolve?: GraphQLFieldResolver<TSource, TContext, TArgs>;
    subscribe?: GraphQLFieldResolver<TSource, TContext, TArgs>;
    isDeprecated?: boolean;
    deprecationReason?: Maybe<string>;
    astNode?: Maybe<FieldDefinitionNode>;
}

Таким образом, чтобы получить тип, вы можете просто сделать:

const type = field.type

Если поле ненулевое, список или какая-то их комбинация, вам нужно "развернуть" тип. Вы можете проверить, является ли какой-либо из типов оболочек списком, когда вы идете:

const { isWrappingType } = require('graphql')

let isList = false
let type = field.type
while (isWrappingType(type)) {
  if (type.name === 'GraphQLList') {
    isList = true
  }
  type = type.ofType
}

Мы можем проверить типы graphql с помощью

      const { GraphQLString } = require('graphql');

const type = field.type

if(field.type === GraphQLString) return 'string'

Как я это использовал? Мне нужно префикс ключа объекта S3 с корневым URL-адресом S3, поэтому я создаю директиву для этого, она проверяет и возвращает строку условий и массив. И код.

      const { SchemaDirectiveVisitor } = require('apollo-server');
const { defaultFieldResolver, GraphQLString, GraphQLList } = require('graphql');

class S3Prefix extends SchemaDirectiveVisitor {
  visitFieldDefinition(field) {
    const { resolve = defaultFieldResolver } = field;
    field.resolve = async function (...args) {
      const result = await resolve.apply(this, args);

      if (field.type === GraphQLString) {
        if (result) {
          return [process.env.AWS_S3_PREFIX, result].join('');
        } else {
          return null;
        }
      }

      if (field.type === GraphQLList) {
        if (result) {
          return result.map((key) => [process.env.AWS_S3_PREFIX, key].join(''));
        } else {
          return [];
        }
      }
    };
  }
}

module.exports = S3Prefix;

Другие вопросы по тегам