|
| 1 | +--- |
| 2 | +title: Introspection |
| 3 | +layout: ../_core/DocsLayout |
| 4 | +category: Learn |
| 5 | +permalink: /learn/introspection/ |
| 6 | +next: /learn/thinking-in-graphs/ |
| 7 | +--- |
| 8 | + |
| 9 | +It's often useful to ask a GraphQL schema for information about what |
| 10 | +queries it supports. GraphQL allows us to do so using the introspection |
| 11 | +system! |
| 12 | + |
| 13 | +For our Star Wars example, the file |
| 14 | +[starWarsIntrospection-test.js](https://github.com/graphql/graphql-js/blob/master/src/__tests__/starWarsIntrospection-test.js) |
| 15 | +contains a number of queries demonstrating the introspection system, and is a |
| 16 | +test file that can be run to exercise the reference implementation's |
| 17 | +introspection system. |
| 18 | + |
| 19 | +We designed the type system, so we know what types are available, but if |
| 20 | +we didn't, we can ask GraphQL, by querying the `__schema` field, always |
| 21 | +available on the root type of a Query. Let's do so now, and ask what types |
| 22 | +are available. |
| 23 | + |
| 24 | +```graphql |
| 25 | +# { "graphiql": true } |
| 26 | +{ |
| 27 | + __schema { |
| 28 | + types { |
| 29 | + name |
| 30 | + } |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | + |
| 40 | +``` |
| 41 | + |
| 42 | +Wow, that's a lot of types! What are they? Let's group them: |
| 43 | + |
| 44 | + - **Query, Character, Human, Episode, Droid** - These are the ones that we |
| 45 | +defined in our type system. |
| 46 | + - **String, Boolean** - These are built-in scalars that the type system |
| 47 | +provided. |
| 48 | + - **__Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, |
| 49 | +__Directive** - These all are preceded with a double underscore, indicating |
| 50 | +that they are part of the introspection system. |
| 51 | + |
| 52 | +Now, let's try and figure out a good place to start exploring what queries are |
| 53 | +available. When we designed out type system, we specified what type all queries |
| 54 | +would start at; let's ask the introspection system about that! |
| 55 | + |
| 56 | +```graphql |
| 57 | +# { "graphiql": true } |
| 58 | +{ |
| 59 | + __schema { |
| 60 | + queryType { |
| 61 | + name |
| 62 | + } |
| 63 | + } |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +And that matches what we said in the type system section, that |
| 68 | +the `Query` type is where we will start! Note that the naming here |
| 69 | +was just by convention; we could have named our `Query` type anything |
| 70 | +else, and it still would have been returned here had we specified it |
| 71 | +was the starting type for queries. Naming it `Query`, though, is a useful |
| 72 | +convention. |
| 73 | + |
| 74 | +It is often useful to examine one specific type. Let's take a look at |
| 75 | +the `Droid` type: |
| 76 | + |
| 77 | +```graphql |
| 78 | +# { "graphiql": true } |
| 79 | +{ |
| 80 | + __type(name: "Droid") { |
| 81 | + name |
| 82 | + } |
| 83 | +} |
| 84 | +``` |
| 85 | + |
| 86 | +What if we want to know more about Droid, though? For example, is it |
| 87 | +an interface or an object? |
| 88 | + |
| 89 | +```graphql |
| 90 | +# { "graphiql": true } |
| 91 | +{ |
| 92 | + __type(name: "Droid") { |
| 93 | + name |
| 94 | + kind |
| 95 | + } |
| 96 | +} |
| 97 | +``` |
| 98 | + |
| 99 | +`kind` returns a `__TypeKind` enum, one of whose values is `OBJECT`. If |
| 100 | +we asked about `Character` instead we'd find that it is an interface: |
| 101 | + |
| 102 | +```graphql |
| 103 | +# { "graphiql": true } |
| 104 | +{ |
| 105 | + __type(name: "Character") { |
| 106 | + name |
| 107 | + kind |
| 108 | + } |
| 109 | +} |
| 110 | +``` |
| 111 | + |
| 112 | +It's useful for an object to know what fields are available, so let's |
| 113 | +ask the introspection system about `Droid`: |
| 114 | + |
| 115 | +```graphql |
| 116 | +# { "graphiql": true } |
| 117 | +{ |
| 118 | + __type(name: "Droid") { |
| 119 | + name |
| 120 | + fields { |
| 121 | + name |
| 122 | + type { |
| 123 | + name |
| 124 | + kind |
| 125 | + } |
| 126 | + } |
| 127 | + } |
| 128 | +} |
| 129 | + |
| 130 | + |
| 131 | + |
| 132 | + |
| 133 | +``` |
| 134 | + |
| 135 | +Those are our fields that we defined on `Droid`! |
| 136 | + |
| 137 | +`id` looks a bit weird there, it has no name for the type. That's |
| 138 | +because it's a "wrapper" type of kind `NON_NULL`. If we queried for |
| 139 | +`ofType` on that field's type, we would find the `String` type there, |
| 140 | +telling us that this is a non-null String. |
| 141 | + |
| 142 | +Similarly, both `friends` and `appearsIn` have no name, since they are the |
| 143 | +`LIST` wrapper type. We can query for `ofType` on those types, which will |
| 144 | +tell us what these are lists of. |
| 145 | + |
| 146 | +```graphql |
| 147 | +# { "graphiql": true } |
| 148 | +{ |
| 149 | + __type(name: "Droid") { |
| 150 | + name |
| 151 | + fields { |
| 152 | + name |
| 153 | + type { |
| 154 | + name |
| 155 | + kind |
| 156 | + ofType { |
| 157 | + name |
| 158 | + kind |
| 159 | + } |
| 160 | + } |
| 161 | + } |
| 162 | + } |
| 163 | +} |
| 164 | + |
| 165 | + |
| 166 | + |
| 167 | + |
| 168 | + |
| 169 | +``` |
| 170 | + |
| 171 | +Let's end with a feature of the introspection system particularly useful |
| 172 | +for tooling; let's ask the system for documentation! |
| 173 | + |
| 174 | +```graphql |
| 175 | +# { "graphiql": true } |
| 176 | +{ |
| 177 | + __type(name: "Droid") { |
| 178 | + name |
| 179 | + description |
| 180 | + } |
| 181 | +} |
| 182 | +``` |
| 183 | + |
| 184 | +So we can access the documentation about the type system using introspection, |
| 185 | +and create documentation browsers, or rich IDE experiences. |
| 186 | + |
| 187 | +This has just scratched the surface of the introspection system; we can |
| 188 | +query for enum values, what interfaces a type implements, and more. We |
| 189 | +can even introspect on the introspection system itself. The specification goes |
| 190 | +into more detail about this topic in the "Introspection" section, and the [introspection](https://github.com/graphql/graphql-js/blob/master/src/type/introspection.js) |
| 191 | +file in GraphQL.js contains code implementing a specification-compliant GraphQL |
| 192 | +query introspection system. |
0 commit comments