Как получить тип поля в директиве схемы 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;