# OpenSpec Change: enterprise-api-gateway - **Change ID**: enterprise-api-gateway - **Package**: `@suaveplan/api-gateway` - **Category**: api/framework - **Target path**: `api/framework/api-gateway` - **Status**: PROPOSED - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/api-gateway.md` --- ## Summary Deliver `@suaveplan/api-gateway` on the genesis branch from scratch at enterprise quality. The package provides a transport-agnostic API gateway layer: pattern-based `Router`, pluggable-strategy `LoadBalancer` (round-robin / random / weighted / consistent-hash), `TransformerPipeline` (request/response rewrite helpers), `GatewayCircuitBreaker` (closed → open → half-open state machine), active `HealthChecker`, per-route retry policy via `@suaveplan/retry`, rate-limiter edge hook via `@suaveplan/rate-limiter`, and a Hono adapter. All wired under `Gateway.handle(request)`. Genesis adds structured errors, Zod config schemas, OTel instrumentation, `@suaveplan/logger` structured logging, property-based tests, and a benchmark suite. --- ## Current-state audit (genesis) The package does not exist on genesis yet — fresh build. Reference: `/mnt/s/web/suaveplan/enterprise/api-gateway.md`. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/error` (`workspace:^`) | `GatewayError` hierarchy | | `@suaveplan/types` (`workspace:^`) | `LoggerLike`, `Clock` | | `@suaveplan/logger` (`workspace:^`) | Per-request structured logging | | `@suaveplan/retry` (`workspace:^`) | Per-route retry + backoff | | `@suaveplan/rate-limiter` (`workspace:^`) | Gateway-edge rate limiting | | `@suaveplan/events` (`workspace:^`) | Circuit-breaker state-change events | | `@suaveplan/api` (`workspace:^`) | Hono adapter mount | | `hono` (`catalog:server`) | HTTP types | | `zod` (`catalog:forms`) | Schema validation | | `@opentelemetry/api` (`catalog:observability`) | Spans + metrics | | `tslib` (`catalog:build`) | Runtime helpers | --- ## Public API surface ### Core classes and factories ```ts function createGateway(config: GatewayConfig): Gateway class Gateway { handle(request: GatewayRequest): Promise } class Router { match(req: GatewayRequest): RouteMatch | null } class LoadBalancer { select(targets: Target[], strategy: BalancerStrategy): Target } class TransformerPipeline { run(req: GatewayRequest): GatewayRequest; runResponse(res: GatewayResponse): GatewayResponse } class GatewayCircuitBreaker { state: CircuitState; record(success: boolean): void } ``` ### Transformer helpers ```ts function addHeaders(headers: Record): RequestTransformer function addPathPrefix(prefix: string): RequestTransformer function addResponseHeaders(headers: Record): ResponseTransformer function removeHeaders(names: string[]): RequestTransformer function rewritePath(pattern: RegExp, replacement: string): RequestTransformer function stripPathPrefix(prefix: string): RequestTransformer ``` ### Interfaces ```ts interface IGateway { handle(request: GatewayRequest): Promise } interface IRouter { match(req: GatewayRequest): RouteMatch | null } interface ILoadBalancer { select(targets: Target[], strategy: BalancerStrategy): Target } interface ITransformerPipeline { run(req: GatewayRequest): GatewayRequest } ``` ### Key types ```ts type GatewayConfig, GatewayRequest, GatewayResponse, GatewayResult type RouteDefinition, RouteMatch, Target, TargetHealth type CircuitBreakerConfig, CircuitBreakerState, CircuitState type BalancerStrategy, HttpMethod, RequestTransformer, ResponseTransformer ``` ### Error codes ```ts type GatewayErrorCode = | "GATEWAY_NO_ROUTE" | "GATEWAY_CIRCUIT_OPEN" | "GATEWAY_UPSTREAM_TIMEOUT" | "GATEWAY_UPSTREAM_UNREACHABLE" | "GATEWAY_CONFIG_INVALID" | "GATEWAY_TRANSFORM_FAILED" ``` ### Constants ```ts DEFAULT_BALANCER_STRATEGY, DEFAULT_FAILURE_THRESHOLD, DEFAULT_RESET_TIMEOUT DEFAULT_SUCCESS_THRESHOLD, DEFAULT_TIMEOUT, GATEWAY_STATUS, MAX_ROUTES ``` --- ## Genesis additions 1. **`fetcher` port** — `GatewayConfig.fetcher: (req: GatewayRequest) => Promise` — explicit outbound HTTP call; injectable for testing. 2. **Zod schemas** for `GatewayConfig`, `RouteDefinition`, `CircuitBreakerConfig` with `createGateway` parse guard. 3. **Structured `GatewayError`** family extending `SuaveplanError`. 4. **OTel** — span per `handle()` call with `gateway.route`, `gateway.target`, `gateway.attempt`, `gateway.circuit_state` attributes; `gateway.requests_total` counter; `gateway.upstream_duration_ms` histogram. 5. **`@suaveplan/retry`** integration on `RouteDefinition.retry` — `attempts`, `backoff`, `jitter`, `retryableStatuses`. 6. **`HealthChecker`** interface + default interval-based probe that updates `Target.health`. 7. **`@suaveplan/rate-limiter`** hook in `Gateway.handle()` checked before forwarding. 8. **Hono adapter** — `gatewayMiddleware(gateway: IGateway): MiddlewareHandler`. 9. **Property-based tests** with `fast-check` on router, balancer, and circuit-breaker invariants. 10. **Benchmark suite** measuring `handle()` latency. --- ## File layout ```text api/framework/api-gateway/ package.json tsconfig.json vitest.config.ts src/ index.ts constants/index.ts types/ common.ts common.md errors/ gateway-errors.ts gateway-errors.md gateway-errors.test.ts index.ts schemas/ config.schema.ts route.schema.ts circuit-breaker.schema.ts core/ gateway/ gateway.ts gateway.md gateway.types.ts gateway.test.ts index.ts router/ router.ts router.md router.test.ts index.ts balancer/ balancer.ts balancer.md balancer.test.ts index.ts transformer/ transformer.ts transformer.md transformer.test.ts index.ts circuit-breaker/ circuit-breaker.ts circuit-breaker.md circuit-breaker.test.ts index.ts health/ health.ts health.md health.test.ts index.ts adapters/ hono-adapter/ hono-adapter.ts hono-adapter.md hono-adapter.test.ts index.ts __benchmarks__/ gateway.bench.ts tests/ integration.test.ts property.test.ts ``` --- ## Impact **Downstream**: any server application that needs to proxy or compose multiple backends. **Prerequisites**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/logger`, `@suaveplan/retry`, `@suaveplan/rate-limiter`, `@suaveplan/events`, `@suaveplan/api`.