# @suaveplan/api-graphql-yoga — GraphQL Yoga engine adapter for @suaveplan/api-graphql. Default GraphQL engine per design doc §10.5. Implements the abstract GraphqlEngine contract from @suaveplan/api-graphql via createYogaGraphqlEngine(opts) — Zod-validated YogaGraphqlOptions, federation through @graphql-tools/schema makeExecutableSchema, schema-collision detection delegated to the canonical GRAPHQL.SCHEMA_COLLISION code, per-request DataLoader scoping bound to RequestContext, depth + complexity guards, masked errors / introspection toggles, graphql-ws subscription transport over an injected api-ws broker, OTel instruments (requests counter, request duration histogram, resolver duration histogram, subscriptions_active gauge, schema_rebuilds counter), 10 GRAPHQL_YOGA_* error codes, and a ./testing subpath re-exporting runGraphqlEngineConformance bound to the Yoga factory. Stage-7 GraphQL Yoga engine adapter. **Default GraphQL engine** for the Suaveplan API plugin system per design doc §10.5 — Bun-friendly, fastest for our usage pattern, and simpler to operate than Apollo Server. Implements the abstract `GraphqlEngine` contract from `@suaveplan/api-graphql` so the same conformance suite (`runGraphqlEngineConformance`) passes against this adapter and any future engine; swapping engines is host-config-only. ## Documentation tree - [execute-helpers](./src/engine/execute-helpers.md) — Houses the smaller execution helpers the Yoga engine uses on every request, kept out of `yoga-engine.ts` so the orchest… - [yoga-engine](./src/engine/yoga-engine.md) — Implements the abstract `GraphqlEngine` contract from `@suaveplan/api-graphql` over the Yoga / `graphql-js` stack. The… - [error-codes](./src/error-codes/error-codes.md) — Defines the frozen `GRAPHQL_YOGA.*` error-code registry and the `GraphqlYogaError` subclass of `SuaveplanError` used th… - [error-codes](./src/error-codes/error-codes.md) — Defines the frozen `GRAPHQL_YOGA.*` error-code registry and the `GraphqlYogaError` subclass of `SuaveplanError` used th… - [federation](./src/federation/federation.md) — Aggregates plugin-side `GraphqlRegistry` contributions into a single `(MergedSchema, ResolverMap)` pair that the Yoga e… - [federation](./src/federation/federation.md) — Aggregates plugin-side `GraphqlRegistry` contributions into a single `(MergedSchema, ResolverMap)` pair that the Yoga e… - [guards](./src/guards/depth-and-complexity.md) — Implements the static depth + complexity guard that the Yoga engine runs after parsing each query and before execution.… - [depth-and-complexity](./src/guards/depth-and-complexity.md) — Implements the static depth + complexity guard that the Yoga engine runs after parsing each query and before execution.… - [instruments](./src/instruments/instruments.md) — Builds and caches the OpenTelemetry instrument bundle the Yoga GraphQL engine emits per request. The bundle covers a co… - [instruments](./src/instruments/instruments.md) — Builds and caches the OpenTelemetry instrument bundle the Yoga GraphQL engine emits per request. The bundle covers a co… - [loaders](./src/loaders/loaders.md) — Defines the per-request loader bag the Yoga engine constructs at pipeline step 7 and disposes at step 11. Two concurren… - [loaders](./src/loaders/loaders.md) — Defines the per-request loader bag the Yoga engine constructs at pipeline step 7 and disposes at step 11. Two concurren… - [options](./src/options/options.md) — Defines `YogaGraphqlOptions`, the Zod-validated configuration boundary that hosts use to wire `createYogaGraphqlEngine`… - [options](./src/options/options.md) — Defines `YogaGraphqlOptions`, the Zod-validated configuration boundary that hosts use to wire `createYogaGraphqlEngine`… - [subscriptions](./src/subscriptions/subscriptions.md) — Bridges the `WsBroker` contract from `@suaveplan/api-ws` to GraphQL `Subscription` resolvers via `AsyncIterable ## Modules - **engine** — `createYogaGraphqlEngine(config)` + helpers (`maskOrPassthrough`, `withTimeout`, `assertIntrospectionAllowed`, `wrapSubscription`). - **federation** — `federatePlugins(entries)` aggregating multiple plugin contributions into one `(MergedSchema, ResolverMap)` pair via `mergeSdl` from `@suaveplan/api-graphql`. - **options** — Zod-validated `YogaGraphqlOptions` + `resolveYogaGraphqlOptions` with safe defaults (`endpoint: "/graphql"`, `maxQueryDepth: 10`, `maxQueryComplexity: 1000`, `timeoutMs: 30000`, `maskedErrors: true`). - **guards** — `enforceGuards(doc, { maxDepth, maxComplexity })` static depth + complexity rejection. - **loaders** — `buildRequestLoaders(factories)` per-request DataLoader bag bound to `RequestContext`. - **subscriptions** — `subscribeBrokerTopic(broker, topic, tenant)` bridges `api-ws` to GraphQL `AsyncIterable`. - **instruments** — `getYogaInstruments()` OTel counter / histogram / gauge bundle. - **error-codes** — 10 `GRAPHQL_YOGA.*` codes + `GraphqlYogaError`. - **testing** — `runYogaConformance(label?, config?)` bound conformance harness. ## Quick start ```ts import { createGraphqlRegistry } from "@suaveplan/api-graphql"; import { createYogaGraphqlEngine } from "@suaveplan/api-graphql-yoga"; const engine = createYogaGraphqlEngine(); const reg = createGraphqlRegistry(); reg.addTypes("type Query { ping: String! }"); reg.addResolvers({ Query: { ping: () => "pong" } }); engine.buildSchema(reg); const result = await engine.executeQuery({ query: "{ ping }" }, ctx); ``` ## Why this engine? - **Bun runtime parity** — graphql-yoga is a thin layer over `graphql-js` and runs natively under Bun without polyfills. - **WebSocket subscriptions over `api-ws`** — `graphql-ws` protocol bridged to the WS broker via `subscribeBrokerTopic`. - **Per-request DataLoader scoping** — design doc §10.3 mandates per-request DataLoader instances; the `buildRequestLoaders` helper enforces this at the engine boundary. - **Depth + complexity guards** — denial-of-service rejection before resolvers run. - **Masked error mode** — flips production error messages to `"Unexpected error."` while preserving the `path` for log-side debugging. ## License MIT — Suaveplan Team.