6.5 KiB
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
function createGateway(config: GatewayConfig): Gateway
class Gateway { handle(request: GatewayRequest): Promise<GatewayResult> }
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
function addHeaders(headers: Record<string, string>): RequestTransformer
function addPathPrefix(prefix: string): RequestTransformer
function addResponseHeaders(headers: Record<string, string>): ResponseTransformer
function removeHeaders(names: string[]): RequestTransformer
function rewritePath(pattern: RegExp, replacement: string): RequestTransformer
function stripPathPrefix(prefix: string): RequestTransformer
Interfaces
interface IGateway { handle(request: GatewayRequest): Promise<GatewayResult> }
interface IRouter { match(req: GatewayRequest): RouteMatch | null }
interface ILoadBalancer { select(targets: Target[], strategy: BalancerStrategy): Target }
interface ITransformerPipeline { run(req: GatewayRequest): GatewayRequest }
Key types
type GatewayConfig, GatewayRequest, GatewayResponse, GatewayResult
type RouteDefinition, RouteMatch, Target, TargetHealth
type CircuitBreakerConfig, CircuitBreakerState, CircuitState
type BalancerStrategy, HttpMethod, RequestTransformer, ResponseTransformer
Error codes
type GatewayErrorCode =
| "GATEWAY_NO_ROUTE"
| "GATEWAY_CIRCUIT_OPEN"
| "GATEWAY_UPSTREAM_TIMEOUT"
| "GATEWAY_UPSTREAM_UNREACHABLE"
| "GATEWAY_CONFIG_INVALID"
| "GATEWAY_TRANSFORM_FAILED"
Constants
DEFAULT_BALANCER_STRATEGY, DEFAULT_FAILURE_THRESHOLD, DEFAULT_RESET_TIMEOUT
DEFAULT_SUCCESS_THRESHOLD, DEFAULT_TIMEOUT, GATEWAY_STATUS, MAX_ROUTES
Genesis additions
fetcherport —GatewayConfig.fetcher: (req: GatewayRequest) => Promise<GatewayResponse>— explicit outbound HTTP call; injectable for testing.- Zod schemas for
GatewayConfig,RouteDefinition,CircuitBreakerConfigwithcreateGatewayparse guard. - Structured
GatewayErrorfamily extendingSuaveplanError. - OTel — span per
handle()call withgateway.route,gateway.target,gateway.attempt,gateway.circuit_stateattributes;gateway.requests_totalcounter;gateway.upstream_duration_mshistogram. @suaveplan/retryintegration onRouteDefinition.retry—attempts,backoff,jitter,retryableStatuses.HealthCheckerinterface + default interval-based probe that updatesTarget.health.@suaveplan/rate-limiterhook inGateway.handle()checked before forwarding.- Hono adapter —
gatewayMiddleware(gateway: IGateway): MiddlewareHandler. - Property-based tests with
fast-checkon router, balancer, and circuit-breaker invariants. - Benchmark suite measuring
handle()latency.
File layout
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.