在 GraphQL 架构中迭代自定义指令
Iterate Over Custom Directives in GraphQL Schema
我有一个简化的 schema.graphql 文件,其中包含一种类型和一个自定义指令(在字段和对象级别)。在 Typescript 中,如何以编程方式获取类型和类型指令,并迭代字段和字段指令?
type Test @myCustomDirective() {
id: String! @myCustomDirective()
}
这 post 说“GraphQL 当前不支持”:
Is there any way to read GraphQL Directives on a Type with Query Introspection?
GitHub 问题表明正在考虑此功能:
https://github.com/graphql/graphql-spec/issues/300
那么 AWS AppSync 是如何做到这一点的呢?见下文。
// The following keeps custom directives:
parse(schema); // Return type: graphql.DocumentNode
// The following removes custom directives:
buildSchema(schema); // Return type: GraphQLSchema
- AWS AppSync > Export Schema > Schema.json 确实包含自定义指令,但它是 AWS AppSync 特定的解决方案,是一项昂贵的 API 操作。
aws appsync get-introspection-schema --api-id abc123 --format JSON --include-directives output.json
我试过 GraphQL Code Generator Introspection 插件。但它从类型和字段中删除了自定义指令。
https://www.graphql-code-generator.com/plugins/introspection
我试过 graphql/utilities 但它也从类型和字段中删除了自定义指令。
graphql.introspectionFromSchema(graphqlSchema)
// or
graphql.graphqlSync({ schema: graphqlSchema, source: graphql.getIntrospectionQuery() }).data as unknown as graphql.IntrospectionQuery;
这种“GraphQL 工具”方法创建了一个可迭代的模式,但可能不是最有效的方法:
“graphql-tools 包允许您使用函数 makeExecutableSchema 从 GraphQL 模式语言创建 GraphQL.js GraphQLSchema 实例”
https://www.graphql-tools.com/docs/generate-schema
import { promises as fs } from 'fs';
import { makeExecutableSchema } from '@graphql-tools/schema';
import gql from 'graphql-tag';
const schemaFile = await fs.readFile(
'./schema.graphql'
);
const executableSchema = makeExecutableSchema({
typeDefs: gql(schemaFile.toString())
});``
const output = executableSchema.getType('Test');
// output.astNode.directives sample output:
{
kind: 'Directive',
name: { kind: 'Name', value: 'myCustomDirective1' },
arguments: [ [Object] ]
},
{
kind: 'Directive',
name: { kind: 'Name', value: 'myCustomDirective' },
arguments: [ [Object] ]
}
// output.astNode['fields'] sample output:
[{
kind: 'FieldDefinition',
description: undefined,
name: { kind: 'Name', value: 'id' },
arguments: [],
type: { kind: 'NamedType', name: [Object] },
directives: [ [Object] ]
}]
我有一个简化的 schema.graphql 文件,其中包含一种类型和一个自定义指令(在字段和对象级别)。在 Typescript 中,如何以编程方式获取类型和类型指令,并迭代字段和字段指令?
type Test @myCustomDirective() {
id: String! @myCustomDirective()
}
这 post 说“GraphQL 当前不支持”:
Is there any way to read GraphQL Directives on a Type with Query Introspection?
GitHub 问题表明正在考虑此功能:
https://github.com/graphql/graphql-spec/issues/300
那么 AWS AppSync 是如何做到这一点的呢?见下文。
// The following keeps custom directives:
parse(schema); // Return type: graphql.DocumentNode
// The following removes custom directives:
buildSchema(schema); // Return type: GraphQLSchema
- AWS AppSync > Export Schema > Schema.json 确实包含自定义指令,但它是 AWS AppSync 特定的解决方案,是一项昂贵的 API 操作。
aws appsync get-introspection-schema --api-id abc123 --format JSON --include-directives output.json
我试过 GraphQL Code Generator Introspection 插件。但它从类型和字段中删除了自定义指令。
https://www.graphql-code-generator.com/plugins/introspection
我试过 graphql/utilities 但它也从类型和字段中删除了自定义指令。
graphql.introspectionFromSchema(graphqlSchema)
// or
graphql.graphqlSync({ schema: graphqlSchema, source: graphql.getIntrospectionQuery() }).data as unknown as graphql.IntrospectionQuery;
这种“GraphQL 工具”方法创建了一个可迭代的模式,但可能不是最有效的方法:
“graphql-tools 包允许您使用函数 makeExecutableSchema 从 GraphQL 模式语言创建 GraphQL.js GraphQLSchema 实例”
https://www.graphql-tools.com/docs/generate-schema
import { promises as fs } from 'fs';
import { makeExecutableSchema } from '@graphql-tools/schema';
import gql from 'graphql-tag';
const schemaFile = await fs.readFile(
'./schema.graphql'
);
const executableSchema = makeExecutableSchema({
typeDefs: gql(schemaFile.toString())
});``
const output = executableSchema.getType('Test');
// output.astNode.directives sample output:
{
kind: 'Directive',
name: { kind: 'Name', value: 'myCustomDirective1' },
arguments: [ [Object] ]
},
{
kind: 'Directive',
name: { kind: 'Name', value: 'myCustomDirective' },
arguments: [ [Object] ]
}
// output.astNode['fields'] sample output:
[{
kind: 'FieldDefinition',
description: undefined,
name: { kind: 'Name', value: 'id' },
arguments: [],
type: { kind: 'NamedType', name: [Object] },
directives: [ [Object] ]
}]