You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生成Schema时自定义Directive无法在输入字段上显示

问题

运行时添加自定义Directive,Directive本身已在输出Schema中正确生成,但应用到特定输入字段时未显示。

创建Directive的代码

const limitDirective = new graphql.GraphQLDirective({
  name: 'myDirective',
  locations: [
    graphql.DirectiveLocation.INPUT_FIELD_DEFINITION,
    graphql.DirectiveLocation.FIELD_DEFINITION,
    graphql.DirectiveLocation.ARGUMENT_DEFINITION
  ],
  args: {
    constraint: {
      type: graphql.GraphQLString,
      description: 'An example argument for myDirective',
    },
    errorCode: {
      type: graphql.GraphQLString,
      description: 'Another example argument for myDirective',
    },
  },
  isRepeatable: true,
});

集成到InputField的代码

let customInput: graphql.GraphQLInputObjectType = new graphql.GraphQLInputObjectType({
  name: "customInput",
  fields: () => ({
    myField: { 
      type: graphql.GraphQLInt, 
      extensions: {
        myDirective:{constraint:"max=50", errorCode:"LIMIT_EXCEEDED"}
      }
    }
  })
})

问题现象

使用print-schema-with-directives函数打印Schema时,输入字段上的Directive未显示(Directive本身已生成):

预期输出

directive @myDirective(
  constraint: String
  errorCode: String
) repeatable on INPUT_FIELD_DEFINITION | FIELD_DEFINITION 

input customInput {
 myField: String @myDirective(constraint: "max=50", errorCode: "LIMIT_EXCEEDED")
}

实际输出

directive @myDirective(
  constraint: String
  errorCode: String
) repeatable on INPUT_FIELD_DEFINITION | FIELD_DEFINITION 

input customInput {
 myField: String
}

解决方法

print-schema-with-directives依赖Schema的AST节点信息来渲染字段上的Directive,通过extensions添加的Directive不会被该工具识别。你需要通过AST节点或Schema转换工具来正确添加Directive:

方法1:手动构建AST节点

直接为输入字段添加包含Directive的AST节点:

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

// 解析生成Directive的AST节点
const directiveAst = parse(`@myDirective(constraint: "max=50", errorCode: "LIMIT_EXCEEDED")`)
  .definitions[0].directives[0];

let customInput: graphql.GraphQLInputObjectType = new graphql.GraphQLInputObjectType({
  name: "customInput",
  fields: () => ({
    myField: { 
      type: graphql.GraphQLInt,
      astNode: {
        kind: 'InputValueDefinition',
        name: { kind: 'Name', value: 'myField' },
        type: { kind: 'NamedType', name: { kind: 'Name', value: 'Int' } },
        directives: [directiveAst]
      }
    }
  })
})

方法2:使用graphql-tools的Schema转换工具

利用mapSchema修改Schema,为指定字段添加Directive:

const { mapSchema, MapperKind } = require('@graphql-tools/utils');
const { parse } = require('graphql');

// 先创建基础Schema
let schema = new graphql.GraphQLSchema({
  directives: [limitDirective],
  types: [customInput]
});

// 转换Schema,为目标字段添加Directive
schema = mapSchema(schema, {
  [MapperKind.INPUT_FIELD]: (fieldConfig, fieldName, typeName) => {
    if (typeName === 'customInput' && fieldName === 'myField') {
      // 初始化AST节点(如果不存在)
      fieldConfig.astNode = fieldConfig.astNode || {
        kind: 'InputValueDefinition',
        name: { kind: 'Name', value: fieldName },
        type: { kind: 'NamedType', name: { kind: 'Name', value: 'Int' } },
        directives: []
      };
      // 添加Directive的AST节点
      fieldConfig.astNode.directives.push(
        parse(`@myDirective(constraint: "max=50", errorCode: "LIMIT_EXCEEDED")`)
          .definitions[0].directives[0]
      );
    }
    return fieldConfig;
  }
});

完成上述修改后,再用print-schema-with-directives打印Schema,输入字段上的Directive就会正常显示。


内容的提问来源于stack exchange,提问作者Hrishikesh Thakkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 00:32:39