Skip to content

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.

crates/nest-rs-graphql/src/config.rs
#[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,
}
FieldEnv varDefaultEffect
pathNESTRS_GRAPHQL__PATH/graphqlMount point for both POST (operations) and GET (playground, when enabled).
playgroundNESTRS_GRAPHQL__PLAYGROUNDfalseWhen true, GET <path> serves the offline playground HTML.
schema_pathNESTRS_GRAPHQL__SCHEMA_PATHschema.graphqlWhere the SDL gets written.
emit_sdlNESTRS_GRAPHQL__EMIT_SDLfalseWhen true, the running app writes its live SDL to schema_path once at boot.
max_depthNESTRS_GRAPHQL__MAX_DEPTH15Bound on AST nesting depth; None disables. See Query limits.
max_complexityNESTRS_GRAPHQL__MAX_COMPLEXITY2000Bound on query complexity score; None disables. See Query limits.
disable_introspectionNESTRS_GRAPHQL__DISABLE_INTROSPECTIONtrueWhen true, the schema rejects introspection queries (production-safe).
max_batch_sizeNESTRS_GRAPHQL__MAX_BATCH_SIZE10Maximum operations in a single HTTP batch request.

Every module’s config follows this rule (framework-wide):

src/module.rs — env-driven
use nest_rs_graphql::GraphqlModule;
#[module(imports = [GraphqlModule::for_root(None)])]
pub struct AppModule;
.env.development
NESTRS_GRAPHQL__PLAYGROUND=true
NESTRS_GRAPHQL__EMIT_SDL=true
NESTRS_GRAPHQL__SCHEMA_PATH=./schema.graphql
src/module.rs — pinned at the import site
use 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.

GraphqlModule mounts on HttpTransport at path:

  • POST <path> — GraphQL operations (queries + mutations).
  • GET <path> — the playground HTML, when playground = 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.

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.

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.

dev workflow
$ 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 change

Apps 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.

Before shipping:

  • NESTRS_GRAPHQL__PLAYGROUND unset or false.
  • NESTRS_GRAPHQL__EMIT_SDL unset or false — production apps don’t rewrite their own SDL.
  • NESTRS_GRAPHQL__MAX_DEPTH set (a value of 15 fits most apps).
  • NESTRS_GRAPHQL__MAX_COMPLEXITY set after calibrating against observed legitimate traffic. See Query limits.
  • path matches 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=true against a known database and diffs against the committed file).
  • crates/nest-rs-graphql/src/config.rs — the GraphqlConfig struct and Config::from_env impl.
  • crates/nest-rs-graphql/src/module.rs — the for_root / register glue that turns the config into route mounts.