# `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`. - `executeQuery` handler accepts a `{ body, headers, context }` envelope — the host's request pipeline decodes the HTTP frame into this shape before dispatch. - `sdl` handler returns the merged SDL synchronously. - Returns a teardown function (currently no-op; reserved for hot reload). - Empty `headers` default — handlers that the host invokes without an explicit map see `{}` rather than `undefined`. ## Usage: Basic ```ts 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: ```ts 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 }; return await engine.executeQuery(req, context as RequestContext); }, sdl: () => engine.sdl() ?? "", }); ``` ## API Reference - `GraphqlHttpHandler` — `(req: { body, headers, context }) → Promise`. - `GraphqlSdlHandler` — `() → string`. - `MountHttpEndpointsArgs` — `{ router, options, executeQuery, sdl }`. - `mountGraphqlHttpEndpoints(args): () → void` — returns teardown. ## Implementation Notes The handler returns a free-form `Record` 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.