Using Schema Introspection
1. Understanding Introspection System
| Field | Returns |
|---|---|
| __schema | Whole schema metadata |
| __type(name) | Single type info |
| __typename | Concrete type at runtime |
2. Querying Schema Types
Example: List all types
{
__schema {
types { name kind description }
queryType { name }
mutationType { name }
subscriptionType { name }
}
}
3. Querying Type Fields
Example: Inspect a type
{
__type(name: "User") {
name
fields {
name
type { name kind ofType { name } }
args { name type { name } defaultValue }
isDeprecated
deprecationReason
}
}
}
4. Querying Input Fields
Example: Inspect input type
{
__type(name: "CreateUserInput") {
inputFields { name type { name } defaultValue description }
}
}
5. Querying Enum Values
Example: Inspect enum
{
__type(name: "Role") {
enumValues(includeDeprecated: false) {
name description isDeprecated deprecationReason
}
}
}
6. Querying Interfaces
Example: Interfaces and implementers
{
__type(name: "Node") {
interfaces { name }
possibleTypes { name }
}
}
7. Querying Possible Types
| Use | Detail |
|---|---|
| Apollo cache | possibleTypes config for fragment matching |
| Codegen | Generate discriminated unions |
| Validation | Verify spread compatibility |
8. Disabling Introspection
Example: Disable in production
new ApolloServer({
schema,
introspection: process.env.NODE_ENV !== "production"
});
Warning: Disabling introspection isn't real security — schema can still be reverse-engineered. Pair with persisted-query allowlists.
9. Using __typename Field
| Where | Returns |
|---|---|
| Object/Interface/Union | Concrete type name string |
| Always queryable | Even on abstract types |
| Apollo cache | Used as part of cache normalization key |
10. Building Schema Documentation
| Tool | Output |
|---|---|
| graphql-markdown | Markdown docs |
| SpectaQL | Static HTML |
| Magidoc | Vue-based site |
| GraphQL Inspector | Schema diff + docs |
11. Implementing Schema Diffing
Example: graphql-inspector diff
graphql-inspector diff main.graphql pr.graphql
# Reports breaking, dangerous, non-breaking changes
| Change Class | Examples |
|---|---|
| Breaking | Field removed, type changed, arg required added |
| Dangerous | New nullable field, default change |
| Safe | New type, new optional arg |