2.9 KiB
endpoints/http — POST /graphql + GET /graphql/sdl
Purpose
endpoints/http mounts the two HTTP endpoints every GraphQL adapter
must expose: POST /graphql for operation dispatch and
GET /graphql/sdl for schema introspection by external tooling. The
paths are driven by ApolloGraphqlOptions so operators can rename
them — useful for shops that namespace internal APIs under /internal/.
The module is framework-agnostic in that it takes a Router from
@suaveplan/api-router and registers handlers via the router's verb
methods. Concrete router adapters (api-router-hono,
api-router-in-memory) consume the same Router interface.
Features
- Mount paths driven by
ApolloGraphqlOptions.endpoint/sdlEndpoint. executeQueryhandler accepts a{ body, headers, context }envelope — the host's request pipeline decodes the HTTP frame into this shape before dispatch.sdlhandler returns the merged SDL synchronously.- Returns a teardown function (currently no-op; reserved for hot reload).
- Empty
headersdefault — handlers that the host invokes without an explicit map see{}rather thanundefined.
Usage: Basic
import { Router } from "@suaveplan/api-router";
import { mountGraphqlHttpEndpoints } from "@suaveplan/api-graphql-apollo/endpoints";
import { parseApolloGraphqlOptions } from "@suaveplan/api-graphql-apollo/options";
const router = new Router();
mountGraphqlHttpEndpoints({
router,
options: parseApolloGraphqlOptions(),
executeQuery: async (r) => ({ data: { ok: true } }),
sdl: () => "type Query { ok: Boolean! }",
});
Usage: Advanced
Drive the executeQuery handler through the engine instead of a stub so the router calls into Apollo Server's lifecycle on every POST:
import { createApolloGraphqlEngine } from "@suaveplan/api-graphql-apollo";
const engine = createApolloGraphqlEngine();
engine.buildSchema(registry);
mountGraphqlHttpEndpoints({
router,
options,
executeQuery: async ({ body, context }) => {
const req = body as { query: string; variables?: Record<string, unknown> };
return await engine.executeQuery(req, context as RequestContext);
},
sdl: () => engine.sdl() ?? "",
});
API Reference
GraphqlHttpHandler—(req: { body, headers, context }) → Promise<unknown>.GraphqlSdlHandler—() → string.MountHttpEndpointsArgs—{ router, options, executeQuery, sdl }.mountGraphqlHttpEndpoints(args): () → void— returns teardown.
Implementation Notes
The handler returns a free-form Record<string, unknown> because the
host's transport adapter serialises the response to wire form. The
SDL handler is synchronous on purpose; SDL is computed once at
buildSchema time and held in memory thereafter. The teardown
closure is a no-op today but exists so callers do not need to rewrite
their host-wiring code when hot reload lands.