Files
skills/docs/api-stack/api/api-graphql-yoga/src/guards/depth-and-complexity.md
2026-05-29 08:20:56 +01:00

2.1 KiB

depth-and-complexity.ts

(no submodules)

Purpose

Implements the static depth + complexity guard that the Yoga engine runs after parsing each query and before execution. Documents that exceed the configured limits are rejected with GRAPHQL_YOGA.DEPTH_EXCEEDED or GRAPHQL_YOGA.COMPLEXITY_EXCEEDED, which lets the host reject denial-of- service payloads (deeply nested fragments, fan-out spreads) before any resolver runs.

The guard is intentionally cheap: a single recursive walk over the already-parsed DocumentNode, no schema awareness, no cost estimator. Hosts that want a smarter cost model (database joins, external service fan-out) compose a stricter guard on top.

Features

  • Tracks deepest SelectionSet nesting level per operation.
  • Counts every Field node touched, expanding fragment spreads inline once per occurrence.
  • Throws subclass GraphqlYogaError with context.depth / context.limit for log-side debugging.

Usage: Basic

import { parse } from "graphql";
import { enforceGuards } from "@suaveplan/api-graphql-yoga";

const doc = parse("{ ping }");
enforceGuards(doc, { maxDepth: 10, maxComplexity: 1000 });

Usage: Advanced

import { parse } from "graphql";
import { enforceGuards } from "@suaveplan/api-graphql-yoga";

const doc = parse(`
    fragment f on Customer { id name orders { id } }
    query { customer(id: "c1") { ...f } }
`);
try {
    enforceGuards(doc, { maxDepth: 3, maxComplexity: 5 });
} catch (error) {
    // GRAPHQL_YOGA.DEPTH_EXCEEDED or COMPLEXITY_EXCEEDED
}

API Reference

  • enforceGuards(document, { maxDepth, maxComplexity }) — throws on violation, returns void on pass.

Implementation Notes

Fragment cycles would cause unbounded recursion if the walker re-visited spreads; in practice the GraphQL validate() pass that runs immediately after parsing rejects cycle-containing documents, so the depth/complexity walker can rely on cycle-free input. Should a future change move the guard ahead of validation, add a Set<string> of seen spreads to short-circuit.