如何在 GraphQL 模式指令中获取字段类型(Node.js,graphql-tools)

How to get the field type in a GraphQL schema directive (Node.js, graphql-tools)

我正在使用实现 SchemaDirectiveVisitorvisitFieldDefinition 功能的架构指令。我想知道架构中定义的字段类型,例如类型是否为数组。

在架构中:

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。

传递给 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

如果该字段是非空字段、列表或两者的某种组合,您将需要 "unwrap" 类型。您可以随时检查是否有任何包装器类型是列表:

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 对象键前面加上 S3 根 URL,所以我创建了一个指令来执行此操作,它检查 returns 条件字符串和数组。和代码。

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;