Files
skills/docs/api-stack/api/api-plugin-graphql/README.md
2026-05-29 08:20:56 +01:00

109 lines
7.2 KiB
Markdown

# @suaveplan/api-plugin-graphql - GraphQL adapter plugin for @suaveplan/api — fluent SchemaBuilder / TypeBuilder for object/input/enum/interface/union types and queries/mutations/subscriptions, ResolverComposer with composable global + per-type middleware, requireRoles / validateArgs / createQueryExecutedMiddleware built-ins, typed graphqlEvents EventBus, defineGraphQLPlugin factory producing a GraphQLPluginDefinition compatible with the definePlugin pattern. 6 GRAPHQL.* error codes, Zod-validated boundary, OTel resolvers_executed_total + resolver_duration_ms instruments.
GraphQL description + resolver-composition layer for `@suaveplan/api`. Server-tier — runs in Bun and Node.
The package provides a typed, builder-driven way to declare GraphQL APIs without raw SDL. It does **not** ship a `graphql-js` executor — its output is a `GraphQLPluginDefinition` consumed by downstream tooling (a future `@suaveplan/api-plugin-graphql-executor`, or any third-party executor).
<!-- begin:auto-docs -->
## Documentation tree
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable `GRAPHQL.*` error-code registry for `@suaveplan/api-plugin-graphql` and the `GraphQLError` class con…
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable `GRAPHQL.*` error-code registry for `@suaveplan/api-plugin-graphql` and the `GraphQLError` class con…
- [otel](./src/otel/instruments.md) — Defines the OpenTelemetry instruments emitted from `createQueryExecutedMiddleware`. The middleware is the only producti…
- [instruments](./src/otel/instruments.md) — Defines the OpenTelemetry instruments emitted from `createQueryExecutedMiddleware`. The middleware is the only producti…
- [plugin](./src/plugin/plugin.md) — Declares `defineGraphQLPlugin(options)`, the factory that produces a `GraphQLPluginDefinition` consumable by the Suavep…
- [plugin](./src/plugin/plugin.md) — Declares `defineGraphQLPlugin(options)`, the factory that produces a `GraphQLPluginDefinition` consumable by the Suavep…
- [resolver](./src/resolver/resolver.md) — Implements `ResolverComposer` (the fluent builder for resolver maps), the two built-in middleware factories `requireRol…
- [resolver](./src/resolver/resolver.md) — Implements `ResolverComposer` (the fluent builder for resolver maps), the two built-in middleware factories `requireRol…
- [schema-builder](./src/schema-builder/schema-builder.md) — Declares `SchemaBuilder`, the fluent builder for GraphQL schema definitions. Consumers describe types, queries, mutatio…
- [schema-builder](./src/schema-builder/schema-builder.md) — Declares `SchemaBuilder`, the fluent builder for GraphQL schema definitions. Consumers describe types, queries, mutatio…
- [schemas](./src/schemas/options.md) — Defines `DefineGraphQLPluginOptionsSchema`, the Zod schema wired at the package boundary inside `defineGraphQLPlugin`.…
- [options](./src/schemas/options.md) — Defines `DefineGraphQLPluginOptionsSchema`, the Zod schema wired at the package boundary inside `defineGraphQLPlugin`.…
- [type-builder](./src/type-builder/type-builder.md) — Declares the `TypeBuilder` class — the inner builder `SchemaBuilder` hands to user-supplied callbacks when declaring ob…
- [type-builder](./src/type-builder/type-builder.md) — Declares the `TypeBuilder` class — the inner builder `SchemaBuilder` hands to user-supplied callbacks when declaring ob…
<!-- end:auto-docs -->
## What you get
- `defineGraphQLPlugin(options)` — typed factory producing a `GraphQLPluginDefinition` (name + merged config + lifecycle hooks + `getSchema()` / `getResolvers()`).
- `SchemaBuilder` — fluent builder for object / input / enum / interface / union types and queries / mutations / subscriptions.
- `TypeBuilder` — chainable field declarations consumed by `SchemaBuilder`.
- `ResolverComposer` — `use` / `useForType` / `addResolver` / `addResolvers` / `build`, with right-to-left middleware composition.
- `requireRoles(...roles)` — auth-check middleware. Throws `GraphQLError(UNAUTHENTICATED | INSUFFICIENT_ROLE)`.
- `validateArgs(validator)` — arg-validation middleware. Throws `GraphQLError(VALIDATION_FAILED)`.
- `graphqlEvents` — typed `EventBus<GraphQLEventMap>` for `graphql:query:executed`.
- `createQueryExecutedMiddleware(bus?)` — production observability middleware recording OTel instruments + emitting events.
- `GRAPHQL_CODES` + `GraphQLError` — 6 stable codes (`UNAUTHENTICATED`, `INSUFFICIENT_ROLE`, `VALIDATION_FAILED`, `INVALID_INPUT`, `TYPE_NOT_FOUND`, `DUPLICATE_RESOLVER`).
- OTel — `graphql.resolvers_executed_total{outcome}` counter and `graphql.resolver_duration_ms` histogram.
## Quick-start
```ts
import {
defineGraphQLPlugin,
ResolverComposer,
SchemaBuilder,
requireRoles,
validateArgs,
createQueryExecutedMiddleware,
graphqlEvents,
} from "@suaveplan/api-plugin-graphql";
const schema = new SchemaBuilder()
.addType("User", (t) =>
t.field("id", "ID", { required: true })
.field("email", "String", { required: true })
)
.addQuery("user", "User", {
args: [{ name: "id", type: "ID", required: true, isList: false }],
})
.addMutation("deleteUser", "Boolean", {
required: true,
args: [{ name: "id", type: "ID", required: true, isList: false }],
})
.build();
const resolvers = new ResolverComposer()
.useForType("Query", createQueryExecutedMiddleware())
.useForType("Mutation", createQueryExecutedMiddleware())
.useForType("Mutation", requireRoles("admin"))
.useForType(
"Mutation",
validateArgs((a) => (typeof a.id === "string" ? null : "id required"))
)
.addResolver("Query", "user", (_p, args) => ({ id: args.id, email: "x@y" }))
.addResolver("Mutation", "deleteUser", () => true)
.build();
graphqlEvents.on("graphql:query:executed", (e) => {
console.log(`${e.operationType}.${e.operationName} ${e.durationMs}ms`);
});
const definition = defineGraphQLPlugin({
name: "users-gql",
version: "0.1.0",
schema,
resolvers,
});
```
## Modules
- [`error-codes/error-codes.md`](src/error-codes/error-codes.md) — `GRAPHQL_CODES`, `GraphQLError`.
- [`otel/instruments.md`](src/otel/instruments.md) — OTel instruments.
- [`plugin/plugin.md`](src/plugin/plugin.md) — `defineGraphQLPlugin`.
- [`resolver/resolver.md`](src/resolver/resolver.md) — `ResolverComposer`, `requireRoles`, `validateArgs`, `createQueryExecutedMiddleware`, `graphqlEvents`.
- [`schema-builder/schema-builder.md`](src/schema-builder/schema-builder.md) — `SchemaBuilder`.
- [`schemas/options.md`](src/schemas/options.md) — `DefineGraphQLPluginOptionsSchema`.
- [`type-builder/type-builder.md`](src/type-builder/type-builder.md) — `TypeBuilder`.
- [`types/graphql.types.md`](src/types/graphql.types.md) — full type surface.
## Scope
This package is functional-parity with upstream `@suaveplan/api-plugin-graphql` (suaveplan main, v1.0.4) plus hardening (typed errors, Zod boundary, OTel). Live execution (`graphql-js`), federation, persisted queries, subscriptions transport, SDL emission, and schema-registry publishing are **out of scope** for this release and are enumerated in `enterprise/api-plugin-graphql.md` §3 as future enterprise upgrades.
## License
MIT.