Skip to content

Commit 2e7872f

Browse files
committed
Initial draft of introspection
1 parent 460caae commit 2e7872f

File tree

2 files changed

+193
-1
lines changed

2 files changed

+193
-1
lines changed

site/learn/Learn-Introspection.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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.

site/learn/Learn-Validation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Validation
33
layout: ../_core/DocsLayout
44
category: Learn
55
permalink: /learn/validation/
6-
next: /learn/thinking-in-graphs/
6+
next: /learn/introspection/
77
---
88

99
By using the type system, it can be predetermined whether a GraphQL query

0 commit comments

Comments
 (0)