加入我们,从10月8日至10日,在纽约市,了解有关GraphQL联邦和API平台工程的最新技巧、趋势和新闻。加入我们于2024年在纽约市举行的GraphQL峰会
文档
免费开始
您正在查看此软件以前的版本的相关文档。 切换到最新稳定版本。

Apollo AST


为了生成客户端代码, 解析您的 以及 它所对应的,并将它们转换为抽象语法树ASTAST)。AST以类型安全、 machine-readable format 的形式表示一个

apollo-kotlin的解析器拥有自己的模块(apollo-ast),您可以独立于apollo-runtimeapollo-api使用。

apollo-ast的功能包括:

安装

apollo-ast依赖添加到您的项目:

build.gradle[.kts]
dependencies {
// ...
implementation("com.apollographql.apollo3:apollo-ast:3.8.5")
}

解析文档

使用parseAsGQLDocument方法从FileString或Okio BufferedSource中解析文档。

val graphQLText = """
query HeroForEpisode(${"$"}ep: Episode) {
hero(episode: ${"$"}ep) {
name
friends {
height
}
foobar
}
}
""".trimIndent()
val parseResult = Buffer().writeUtf8(graphQLText).parseAsGQLDocument()

该方法返回一个GQLResult<GQLDocument>,其中包含文档和/或解析问题,每个问题都可以具有WARNINGERROR的严重性。由于可能有警告,因此可能同时具有有效的文档和问题。

要获取文档并在出错时抛出,请使用valueAssertNoErrors()

val queryGqlDocument = parseResult.valueAssertNoErrors()

GQLDocument是AST的根。它包含代表GraphQL文档的GQLDefinition列表。

AST中的所有节点都是GQLNode的子类(所有都以GQL为前缀命名)。每个子类都公开针对相应节点类型相关的特定属性和方法。

AST结构示例

在下面的 HeroForEpisode 示例 ,这是解析器返回的 AST 结构:

GQLDocument
└─GQLOperationDefinition query "HeroForEpisode"
├─GQLVariableDefinition "ep": "Episode"
└─GQLSelectionSet
└─GQLField "hero"
├─GQLSelectionSet
│ ├─GQLField "name"
│ ├─GQLField "friends"
│ │ └─GQLSelectionSet
│ │ └─GQLField "height"
│ └─GQLField "foobar"
└─GQLArguments
└─GQLArgument "episode"
└─GQLVariableValue "ep"

请注意,这个结构和其节点名称紧密遵循 GraphQL 规范

验证输入

除了解析外,apollo-ast 库还提供了对 GraphQL 文档进行高级验证的方法。

要验证一个解析出的 GQLDocument:

  • 如果文档代表一个模式,请调用 validateAsSchema 方法。
  • 如果文档代表一个或多个操作,请调用 validateAsExecutable 方法。

validateAsSchema

validateAsSchema 返回一个 GQLResult<Schema>. 以下代码片段解析并验证了一个使用未定义的 @private)的短无效方案:

val schemaText = """
type Query {
hero(episode: Episode): Character
}
enum Episode {
NEWHOPE
EMPIRE
}
type Character @private {
name: String
height: Int @deprecated
friends: [Character]
}
""".trimIndent()
val schemaGQLDocument = Buffer().writeUtf8(schemaText).parseAsGQLDocument().valueAssertNoErrors()
val schemaResult = schemaGQLDocument.validateAsSchema()
println(schemaResult.issues.map { it.severity.name + ": " + it.message })

当执行此代码片段时,将打印 [WARNING: Unknown directive 'private']

因为这只是一个警告而不是错误,您仍然可以使用返回的 schemaResult.valueAssertNoErrors()

validateAsExecutable

validateAsExecutable 方法检查文档定义的操作是否与提供的特定 Schema 有效。您可以调用代表该方案的 GQLDocumentvalidateAsSchema 方法来获取此 Schema 参数:

val schema = schemaGQLDocument.validateAsSchema().valueAssertNoErrors()
val executableIssues = queryGqlDocument.validateAsExecutable(schema)
println(executableIssues.map { it.severity.name + ": " + it.message })

如果 queryGqlDocument 查询了一个弃用的 且拼写错误另一个,此代码片段可能打印以下内容:

[WARNING: Use of deprecated field 'height', ERROR: Can't query 'frends' on type 'Character']

输出 SDL

您可以使用 toUtf8GQLDocument 输出为标准的 GraphQL 语法

// Returns a string
println(queryGqlDocument.toUtf8())
// Output to a File
queryGqlDocument.toUtf8(file)
// Output to an Okio BufferedSink
queryGqlDocument.toUtf8(sink)

转换 AST

您可以使用

GQLDocumenttransform 方法来修改现有的 AST。

您传递transform一个接受GQLNode作为参数并返回用以操作AST指令的lambda表达式:

  • Continue:保持节点不变并继续访问子节点
  • Delete:删除节点
  • Replace(GQLNode):将节点替换为给定的节点

该方法会遍历AST并执行对于每个节点的lambda表达式,然后根据lambda的返回值在AST上执行操作。

需要注意的是,使用DeleteReplace时,不会自动访问节点的子节点,因此在需要时请递归调用transform

例如,以下代码段从在queryGqlDocument中定义的操作中移除所有名为restrictedField,并打印结果:

val transformedQuery = queryGqlDocument.transform{ node ->
if (node is GQLField && node.name == "restrictedField") {
TransformResult.Delete
} else {
TransformResult.Continue
}
}
println(transformedQuery!!.toUtf8())
Previous
Kotlin原生
Next
基于响应的代码生成
评分文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,以Apollo GraphQL名义。

隐私政策

公司