Configuration
GraphqlModule::for_root(None) reads NESTRS_GRAPHQL__* from the
environment; GraphqlModule::for_root(Some(config)) pins a value
that wins over env. Every field is settable both ways — pin host
behaviour in code, leave secrets and per-environment toggles to env.
Defaults are production-safe: the playground stays off, the SDL emit
stays off, the mount path is /graphql.
The config struct
Section titled “The config struct”#[config(namespace = "graphql")]pub struct GraphqlConfig { /// Default `/graphql`. pub path: String, /// Default `false` (production-safe). pub playground: bool, /// Where the committed SDL lives. Default `schema.graphql`. pub schema_path: PathBuf, /// (Re)write `schema_path` from the live schema once at boot. /// Default `false`. A write failure is logged, never fatal. pub emit_sdl: bool, /// Reject queries nesting deeper than this. Default `Some(15)` /// (production-safe); set `None` to disable. See Query limits. pub max_depth: Option<usize>, /// Reject queries whose complexity score exceeds this. Default /// `Some(2000)` (production-safe); set `None` to disable. See Query limits. pub max_complexity: Option<usize>, /// Disable GraphQL introspection. Default `true` (production-safe). pub disable_introspection: bool, /// Maximum operations in a single HTTP batch request. Default `10`. pub max_batch_size: usize,}| Field | Env var | Default | Effect |
|---|---|---|---|
path | NESTRS_GRAPHQL__PATH | /graphql | Mount point for both POST (operations) and GET (playground, when enabled). |
playground | NESTRS_GRAPHQL__PLAYGROUND | false | When true, GET <path> serves the offline playground HTML. |
schema_path | NESTRS_GRAPHQL__SCHEMA_PATH | schema.graphql | Where the SDL gets written. |
emit_sdl | NESTRS_GRAPHQL__EMIT_SDL | false | When true, the running app writes its live SDL to schema_path once at boot. |
max_depth | NESTRS_GRAPHQL__MAX_DEPTH | 15 | Bound on AST nesting depth; None disables. See Query limits. |
max_complexity | NESTRS_GRAPHQL__MAX_COMPLEXITY | 2000 | Bound on query complexity score; None disables. See Query limits. |
disable_introspection | NESTRS_GRAPHQL__DISABLE_INTROSPECTION | true | When true, the schema rejects introspection queries (production-safe). |
max_batch_size | NESTRS_GRAPHQL__MAX_BATCH_SIZE | 10 | Maximum operations in a single HTTP batch request. |
The dual path
Section titled “The dual path”Every module’s config follows this rule (framework-wide):
use nest_rs_graphql::GraphqlModule;
#[module(imports = [GraphqlModule::for_root(None)])]pub struct AppModule;NESTRS_GRAPHQL__PLAYGROUND=trueNESTRS_GRAPHQL__EMIT_SDL=trueNESTRS_GRAPHQL__SCHEMA_PATH=./schema.graphqluse nest_rs_graphql::{GraphqlConfig, GraphqlModule};use std::path::PathBuf;
#[module(imports = [ GraphqlModule::for_root(GraphqlConfig { path: "/api/graphql".into(), schema_path: PathBuf::from("./schema.graphql"), ..Default::default() }),])]pub struct AppModule;Mix both freely — pin the mount path in code (the reverse proxy
depends on it), leave playground and emit_sdl to env.
Mount path
Section titled “Mount path”GraphqlModule mounts on HttpTransport at path:
POST <path>— GraphQL operations (queries + mutations).GET <path>— the playground HTML, whenplayground = true.
The path is a nested route on the HTTP transport, so the surrounding
HttpModule config (host, port, CORS, TLS) applies as usual.
HTTP / Configuration covers the transport itself.
The playground
Section titled “The playground”When playground = true, GET <path> serves
async_graphql::http::playground_source — the offline HTML, no CDN
fetch. The page hits the same mount path for its requests, so a
reverse proxy or a path = "/api/graphql" override Just Works.
In dev, the playground is the fastest way to read the schema, run a query, and inspect the response with field-level docs. In production, keep it off and rely on the committed SDL plus introspection-aware clients reading from a sandbox environment.
SDL emission
Section titled “SDL emission”emit_sdl = true rewrites schema_path from the live schema once at
boot. The SDL gets sorted (types, fields, arguments, enum values) so
two builds of the same schema produce byte-identical files — the diff
in git tells you what changed.
$ NESTRS_GRAPHQL__EMIT_SDL=true nestrs run dev api# schema.graphql is rewritten before the app starts serving$ git diff schema.graphql # see the wire changeApps commit schema.graphql next to Cargo.toml. A schema change
shows up in a code review without a separate generator pass or a CI
drift-check.
A write failure is logged at warn level (nest_rs::graphql
target), never fatal — the app still starts. The path is resolved
relative to the working directory the app was launched from.
Production checklist
Section titled “Production checklist”Before shipping:
NESTRS_GRAPHQL__PLAYGROUNDunset orfalse.NESTRS_GRAPHQL__EMIT_SDLunset orfalse— production apps don’t rewrite their own SDL.NESTRS_GRAPHQL__MAX_DEPTHset (a value of 15 fits most apps).NESTRS_GRAPHQL__MAX_COMPLEXITYset after calibrating against observed legitimate traffic. See Query limits.pathmatches what your gateway / ingress routes to.- The SDL committed in git is the one the production binary serves
(the CI build runs with
emit_sdl=trueagainst a known database and diffs against the committed file).
Reference
Section titled “Reference”crates/nest-rs-graphql/src/config.rs— theGraphqlConfigstruct andConfig::from_envimpl.crates/nest-rs-graphql/src/module.rs— thefor_root/registerglue that turns the config into route mounts.