验证

    对于我们的《星球大战》的案例, 这个文件包含了若干对于各种无效查询的演示,它也是一个测试文件,用于检测参考实现的验证器。

    上面这个查询是有效的。我们来看看一些无效查询……

    1. {
    2. hero {
    3. ...NameAndAppearancesAndFriends
    4. }
    5. }
    6. fragment NameAndAppearancesAndFriends on Character {
    7. name
    8. appearsIn
    9. friends {
    10. }
    11. }

    查询字段的时候,我们只能查询给定类型上的字段。因此由于 hero 返回 Character 类型,我们只能查询 Character 上的字段。因为这个类型上没有 favoriteSpaceship 字段,所以这个查询是无效的:

    当我们查询一个字段时,如果其返回值不是标量或者枚举型,那我们就需要指明想要从这个字段中获取的数据。 返回 Character 类型,我们也请求了其中像是 nameappearsIn 的字段;但如果将其省略,这个查询就变成无效的了:

    1. # { "graphiql": true }
    2. # 无效:hero 不是标量,需要指明下级字段
    3. {
    4. hero
    5. }

    我们之前提到过,只有目标类型上的字段才可查询;当我们查询 hero 时,它会返回 Character,因此只有 Character 上的字段是可查询的。但如果我们要查的是 R2-D2 的 primary function 呢?

    1. # { "graphiql": true }
    2. # 无效:primaryFunction 不存在于 Character 之上
    3. {
    4. hero {
    5. primaryFunction
    6. }

    这个查询是无效的,因为 primaryFunction 并不是 Character 的字段。我们需要某种方法来表示:如果对应的 CharacterDroid,我们希望获取 primaryFunction 字段,而在其他情况下,则忽略此字段。我们可以使用之前引入的“片段”来解决这个问题。先在 Droid 上定义一个片段,然后在查询中引入它,这样我们就能在定义了 primaryFunction 的地方查询它。

    1. # { "graphiql": true }
    2. {
    3. hero {
    4. name
    5. ... on Droid {
    6. primaryFunction
    7. }
    8. }

    这只是验证系统的冰山一角;事实上需要一大套验证规则才能保证 GraphQL 查询的语义意义。规范中的“验证”章节有关于本话题更详细的内容,GraphQL.js 的 validation 目录包含了规范兼容的 GraphQL 验证器实现代码。