iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Introspection

GraphQL introspection: querying the schema itself. Useful for tooling, dangerous on public APIs.

GraphQL — introspection

EXAMPLE
# ===== What introspection is =====
# GraphQL ships with a meta-query that returns the schema:
{
  __schema {
    types {
      name
      kind
      fields {
        name
        type { name kind }
      }
    }
  }
}

# Powers:
# - GraphiQL / Apollo Studio explorers
# - Codegen tools (graphql-codegen)
# - IDE plugins (VS Code GraphQL)
# - Client cache normalisation

# ===== Useful introspection queries =====
# All type names:
{ __schema { types { name } } }

# Specific type:
{ __type(name: "User") { name fields { name type { name } } } }

# All queries:
{ __schema { queryType { fields { name } } } }

# Directives:
{ __schema { directives { name args { name } locations } } }

# ===== Tooling =====
# graphql-codegen extracts schema + queries for typed clients:
# codegen.yml
schema: http://localhost:4000/graphql
documents: 'src/**/*.graphql'
generates:
  src/generated/graphql.ts:
    plugins: [typescript, typescript-operations, typescript-react-apollo]

# ===== Security concerns =====
# Public APIs that expose introspection give attackers:
# - Full schema (every type, field, query, mutation)
# - Argument types (validation hints)
# - Custom directive locations

# Common decision: ENABLE introspection in dev / staging; DISABLE in production.

# ===== Disable in production =====
# Apollo Server:
import { ApolloServer } from '@apollo/server';
const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: process.env.NODE_ENV !== 'production',
});

# Yoga:
import { createYoga } from 'graphql-yoga';
const yoga = createYoga({
  schema,
  graphiql: false,
  plugins: [
    process.env.NODE_ENV === 'production' && {
      onValidate({ document }) {
        // Reject queries that touch __schema or __type
      },
    },
  ].filter(Boolean),
});

# Or use graphql-disable-introspection:
import { disableIntrospection } from '@envelop/disable-introspection';

# ===== Alternative: persisted queries =====
# If you use persisted operations (allowlist), introspection-via-arbitrary-query becomes
# moot because clients can ONLY send allowlisted queries.

# ===== Tooling without runtime introspection =====
# Even with introspection disabled in prod, your build can dump the schema:
npx get-graphql-schema http://localhost:4000/graphql > schema.graphql

# Ship the schema with the codegen pipeline; don't query prod.

# ===== Patterns =====
# - Enable in dev / staging
# - Disable in production (or restrict to authenticated admin)
# - Persisted operations for public APIs
# - Schema export in build for codegen
# - Schema registry (Apollo Studio / GraphOS) for cross-service composition

# ===== Pitfalls =====
# - Production introspection leaks the entire API surface
# - Tools assume introspection always available -> fail in prod
# - Disabling introspection without persisted ops -> arbitrary queries still allowed
# - Forgetting to publish schema to registry on deploy

Why it matters

Introspection is the schema-query mechanism that powers tooling. Enable in dev, disable in prod (or guard with auth + persisted operations). Use schema export + registry for codegen and cross-service composition; never query prod for the schema.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
query { __schema { types { name } } }
Try it Yourself »

Discussion

Loading…