内省

    在我们的星战例子里,文件 包含了一系列展示了内省系统的查询,它也是一个测试文件,用来检验参考实现的内省系统。

    如果是我们亲自设计了类型,那我们自然知道哪些类型是可用的。但如果类型不是我们设计的,我们也可以通过查询 字段来向 GraphQL 询问哪些类型是可用的。一个查询的根类型总是有 __schema 这个字段。现在来试试,查询一下有哪些可用的类型。

    哇,有好多类型!它们都是什么?我们来总结一下:

    • Query, Character, Human, Episode, Droid - 这些是我们在类型系统中定义的类型。
    • String, Boolean - 这些是内建的标量,由类型系统提供。
    • __Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive - 这些有着两个下划线的类型是内省系统的一部分。

    现在,来试试找到一个可以探索出有哪些可用查询的地方。当我们设计类型系统的时候,我们确定了一个所有查询开始的地方,来问问内省系统它是什么!

    1. # { "graphiql": true }
    2. {
    3. __schema {
    4. queryType {
    5. name
    6. }
    7. }
    8. }

    有时候也需要检验一个特定的类型。来看看 Droid 类型:

    如果我们想要更了解 Droid 呢?例如,它是一个接口还是一个对象?

    1. # { "graphiql": true }
    2. {
    3. name
    4. kind
    5. }

    kind 返回一个枚举类型 __TypeKind,其中一个值是 OBJECT。如果我们改问 Character,我们会发现它是一个接口:

    对于一个对象来说,知道它有哪些字段是很有用的,所以来问问内省系统 Droid 有哪些字段:

    1. # { "graphiql": true }
    2. {
    3. __type(name: "Droid") {
    4. name
    5. fields {
    6. name
    7. type {
    8. name
    9. kind
    10. }
    11. }
    12. }

    id 看起来有点儿奇怪,这个类型没有名字。这是因为它是一个 NON_NULL 类型的“包装” 。如果我们请求它的 ofType 字段,我们会发现它是 ID ,告诉我们这是一个非空的 ID。

    相似地,friendsappearsIn 都没有名字,因为它们都是 LIST 包装类型。我们可以看看它们的 ofType,就能知道它们是装什么东西的列表。

    最后我们来看看内省系统特别适合用来开发工具的特性,我们来向内省系统请求文档!

    1. # { "graphiql": true }
    2. {
    3. __type(name: "Droid") {
    4. name
    5. description
    6. }

    因此我们可以通过内省系统接触到类型系统的文档,并做出文档浏览器,或是提供丰富的 IDE 体验。