验证
对于我们的《星球大战》的案例, 这个文件包含了若干对于各种无效查询的演示,它也是一个测试文件,用于检测参考实现的验证器。
上面这个查询是有效的。我们来看看一些无效查询……
{
hero {
...NameAndAppearancesAndFriends
}
}
fragment NameAndAppearancesAndFriends on Character {
name
appearsIn
friends {
}
}
查询字段的时候,我们只能查询给定类型上的字段。因此由于 hero
返回 Character
类型,我们只能查询 Character
上的字段。因为这个类型上没有 favoriteSpaceship
字段,所以这个查询是无效的:
当我们查询一个字段时,如果其返回值不是标量或者枚举型,那我们就需要指明想要从这个字段中获取的数据。 返回 Character
类型,我们也请求了其中像是 name
和appearsIn
的字段;但如果将其省略,这个查询就变成无效的了:
# { "graphiql": true }
# 无效:hero 不是标量,需要指明下级字段
{
hero
}
我们之前提到过,只有目标类型上的字段才可查询;当我们查询 hero
时,它会返回 Character
,因此只有 Character
上的字段是可查询的。但如果我们要查的是 R2-D2 的 primary function 呢?
# { "graphiql": true }
# 无效:primaryFunction 不存在于 Character 之上
{
hero {
primaryFunction
}
这个查询是无效的,因为 primaryFunction
并不是 Character
的字段。我们需要某种方法来表示:如果对应的 Character
是 Droid
,我们希望获取 primaryFunction
字段,而在其他情况下,则忽略此字段。我们可以使用之前引入的“片段”来解决这个问题。先在 Droid
上定义一个片段,然后在查询中引入它,这样我们就能在定义了 primaryFunction
的地方查询它。
# { "graphiql": true }
{
hero {
name
... on Droid {
primaryFunction
}
}
这只是验证系统的冰山一角;事实上需要一大套验证规则才能保证 GraphQL 查询的语义意义。规范中的“验证”章节有关于本话题更详细的内容,GraphQL.js 的 validation 目录包含了规范兼容的 GraphQL 验证器实现代码。