加入我们,于10月8日至10日在纽约市学习最新的GraphQL联盟和API平台工程技巧、趋势和新闻。加入我们在纽约市举办的GraphQL峰会2024
文档
免费开始

指令

配置GraphQL类型、字段和参数


查找 ?查看联邦特定GraphQL指令

一个指令用于装饰 GraphQL 架构或操作的以额外的配置。像(以及Apollo 客户端这样的工具可以读取 GraphQL 文档的指令并执行相应的自定义逻辑。

前面都有一个@字符,例如:

schema.graphql
type ExampleType {
oldField: String @deprecated(reason: "Use `newField`.")
newField: String
}

此示例展示了@deprecated 指令,它是一个默认指令(即它是 GraphQL 规范的一部分GraphQL specification)。它展示了关于指令的以下信息:

  • 指令可以有自己的 (在这个例子中是reason)。
  • 指令出现在它们装饰的对象(在这个例子中是oldField 字段)的声明之后。

有效位置

每个 指令只能出现在 特定 的位置,这些位置在一个 GraphQL 模式或 操作 中定义。

例如,下面是 GraphQL 规范中 @deprecated 指令的 定义:

directive @deprecated(
reason: String = "No longer supported"
) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE

这表示 @deprecated 可以装饰四个列出位置中的任何一个。同时请注意,其 reason 是可选的,并提供了默认值。下面提供了每个位置的用法示例:

schema.graphql
# ARGUMENT_DEFINITION
# Note: @deprecated arguments _must_ be optional.
directive @withDeprecatedArgs(
deprecatedArg: String @deprecated(reason: "Use `newArg`")
newArg: String
) on FIELD
type MyType {
# ARGUMENT_DEFINITION (alternate example on a field's args)
fieldWithDeprecatedArgs(name: String @deprecated): String
# FIELD_DEFINITION
deprecatedField: String @deprecated
}
enum MyEnum {
# ENUM_VALUE
OLD_VALUE @deprecated(reason: "Use `NEW_VALUE`.")
NEW_VALUE
}
input SomeInputType {
nonDeprecated: String
# INPUT_FIELD_DEFINITION
deprecated: String @deprecated
}

如果 @deprecated 出现在 GraphQL 文档的其他地方,则会引发错误。

如果您创建了一个 自定义指令,则需要在您的模式中定义它(及其有效位置)。您不需要定义 默认指令(例如 @deprecated)。

模式指令与操作指令

通常,给定的 指令 只出现在 独占独占GraphQL 操作(虽然规范允许这样做,但很少同时出现)。

例如,在 默认指令中,@deprecated 是模式独占指令,而 @skip@include 是操作独占指令。

GraphQL 规范 列出了所有可能的 指令 位置。模式位置列在 TypeSystemDirectiveLocation 下,操作位置列在 ExecutableDirectiveLocation 下。

默认指令

GraphQL 规范 定义以下默认 指令

指令描述
@deprecated(reason: String)将字段或枚举值的模式定义为已弃用,带有可选的原因。
@skip(if: Boolean!)如果 true,则装饰的 field 或 fragment 在操作中不会被 GraphQL 服务器解析。
@include(if: Boolean!)如果 false,则装饰的 field 或 fragment 在操作中不会被 GraphQL 服务器解析。

自定义指令

⚠️ Apollo Server 不提供 内置 支持 将模式转换为自定义指令的功能。

您的模式可以定义自定义 指令,然后用于装饰模式的其他部分:

# Definition
directive @uppercase on FIELD_DEFINITION
type Query {
# Usage
hello: String @uppercase
}

如果您想定义一个自定义模式指令来 转换 可执行模式的行为,并在向 Apollo Server 提供 之前,我们建议使用 @graphql-tools 库。请查看我们的 使用自定义指令转换模式的示例。

在子图中

在使用自定义 指令的程序化图之前,请确保考虑以下事项:

  • 如果多个 都可以解析特定的字段,则几乎每个子图都应该针对该字段应用一组相同的自定义指令(定义相同)。否则,该字段的行为可能会根据解析它的 个子图而有所不同。
  • 因为指令针对的是单个子图,所以技术上不同的子图可以定义具有不同逻辑的相同的指令。如前所述,如果自定义指令在多个子图中用于解析特定字段,则应在子图中以相同的逻辑定义相同的指令。 组合过程中不会检测或警告此类不一致。
  • 组合过程对待 可执行的(客户端)类型系统(服务器端)指令 的方式不同:
    • 如果一个可执行 指令被组合到超级图模式中,那么:
      • 所有子图都定义了相同的指令。
      • 该指令未包含在任何 @composeDirective 指令中。
    • 指令不是组合到 的,但它们可以通过@composeDirective指令提供信息。

转换函数

正如我们的示例所示,在Apollo Server 3和4中,您可以为每个子图模式的自定义指令定义一个转换函数

要将转换函数应用到可执行的子图模式,您首先像平常一样使用buildSubgraphSchema生成子图模式:

let subgraphSchema = buildSubgraphSchema({ typeDefs, resolvers });

将转换函数应用于所有转换函数后,您可以像平常一样将最终的子图模式提供给ApolloServer构造函数:

// Transformer function for an @upper directive
subgraphSchema = upperDirectiveTransformer(subgraphSchema, 'upper');

在应用所有转换函数后,您将最终的子图模式作为参数传递给ApolloServer构造函数,就像您之前做的那样:

const server = new ApolloServer({
schema: subgraphSchema,
// ...other options...
});
上一节
自定义标量
下一节
解析器
评价文章评价在GitHub编辑编辑论坛Discord

©2024Apollo Graph Inc.,作为Apollo GraphQL进行业务。

隐私政策

公司