Skip to content

ADR-025: API layer — HTTP API Gateway and SST

Status Accepted
Date 2026-04-10
Deciders CTO, Head of Platform Engineering
Affects repos bank-core, bank-kyc, bank-aml, bank-payments, bank-credit, bank-risk-platform, bank-platform, bank-app

Context

ADR-022 established the serverless execution model and trunk-based development but deferred two decisions: the specific API Gateway variant and the IaC/deployment framework. Eight system domain repositories each need a consistent API and deployment pattern before any domain can begin building. The framework choice also determines how Lambda functions are defined, tested locally, and deployed.

Decision

AWS API Gateway HTTP API (v2) for all HTTP endpoints. SST v3 (Ion) as the deployment framework across all repositories.

Concern Decision
API Gateway variant HTTP API (v2) — lower cost (~70% less than REST API), lower latency, sufficient feature set for all identified use cases
Deployment framework SST v3 (Ion) — TypeScript-first, live Lambda development, Pulumi as infrastructure engine
IaC engine Pulumi — used via SST v3 under the hood. This resolves the open IaC tooling decision from ADR-022
Language TypeScript throughout all repos
Local development SST Live Lambda — local code runs against real AWS infrastructure; no local emulator needed for Lambda logic

API architecture pattern

Customer mobile app (bank-app)
    → Edge API Gateway (shared, customer-facing)
        → Domain Lambda functions (per system domain)
            → Domain API Gateway (per system domain, internal)

Staff web app (bank-app, back-office mode)
    → Staff API Gateway (shared, staff-facing)
        → Domain Lambda functions

Service-to-service calls
    → Direct Lambda invocation (not through API Gateway)
    → EventBridge events for async cross-domain communication (ADR-029, superseded by ADR-051; see ADR-051 for current EventBridge bus naming convention)

Each system domain repository deploys its own API Gateway and Lambda functions via SST. The edge gateways (customer-facing and staff-facing) are managed by bank-app and route to domain APIs. Internal service calls bypass API Gateway entirely — direct Lambda invocation or EventBridge events.

SST and IaC resolution

SST v3 (Ion) uses Pulumi as its infrastructure engine. Adopting SST means Pulumi is the IaC layer for all serverless infrastructure. State is stored in an S3 bucket per environment (Pulumi S3 backend), with DynamoDB locking. This closes the open IaC tooling question from ADR-022 — no separate IaC tool decision is required.

Terraform and AWS CDK are not used. Per-environment variable overrides are SST stage configs — consistent with DT-010 requirement 22.

Cold start management

Lambda cold starts must not breach NFR thresholds on critical paths:

Path NFR Mitigation
Payment processing NFR-025 (≤ 5s domestic) Provisioned concurrency on payment Lambda
KYC/eIDV check NFR-002 (onboarding p90 ≤ 5 min) Provisioned concurrency on KYC Lambda
Fraud scoring inference NFR-021 (p99 ≤ 200ms) Provisioned concurrency on fraud scorer
All other paths On-demand cold start acceptable

Provisioned concurrency is configured per environment in SST stage config. UAT performance tests must validate that cold-start behaviour on provisioned functions meets NFR thresholds before prod promotion.

Consequences

Positive: - HTTP API v2 is significantly cheaper and lower latency than REST API v1 for the same workload - SST Live Lambda eliminates the local emulator complexity — developers work against real Lambda with local code hot-reload - SST v3/Pulumi resolves the deferred IaC decision from ADR-022 cleanly — one framework handles both deployment and infrastructure - TypeScript throughout gives consistent tooling and type-sharing between Lambda functions and the frontend (bank-app) - Per-domain API gateways provide blast radius isolation — a misconfiguration in one domain's gateway cannot affect another

Negative: - SST v3 is relatively new (Ion architecture launched 2024) — less long-term production evidence than Serverless Framework or SAM - Pulumi state (S3 backend) must be bootstrapped before any SST deploy can run — small upfront cost - Provisioned concurrency for critical paths adds cost — budgeted as a necessary NFR cost, not optional

Alternatives considered

AWS REST API (v1): Rejected. Feature set not required for identified use cases. ~70% more expensive than HTTP API for equivalent traffic. Only justified if API keys, per-method throttling, or request validation are required — none identified.

Serverless Framework: Rejected. Third-party dependency with slower adoption of new AWS features. SST v3 has better TypeScript integration and live development experience.

AWS SAM: Rejected. AWS-native but less developer experience investment. No live Lambda development equivalent. Better suited to simple single-function projects than an 8-repo platform.

Single shared API Gateway: Rejected. A single gateway for all 8 domains creates a blast radius and deployment coupling problem. Per-domain gateways with an edge routing layer is the correct pattern for independent deployability.



Signoff record

Date Name Role Status
2026-04-10 Ross Millen CTO Approved
2026-04-10 Ross Millen Head of Architecture Approved
2026-04-10 Ross Millen Head of Data Approved

Capabilities

Capability Description Relationship
CAP-061 Commercial API programme & developer portal architecturally required — HTTP API Gateway v2 is the external API surface
CAP-074 Role-scoped API gateway enabled — per-domain API gateways with blast-radius isolation
CAP-121 API rate limiting & throttling enabled — HTTP API Gateway provides built-in rate limiting
CAP-122 API versioning & request routing enabled — per-domain gateways with edge routing layer

ADR Title Relationship
ADR-022 CI/CD and deployment strategy resolves the deferred IaC tooling decision from ADR-022
ADR-023 Cloud provider and region strategy AWS-specific implementation
ADR-029 (superseded by ADR-051; see ADR-051 for current EventBridge bus naming convention) Domain event routing via Amazon EventBridge EventBridge handles async; this ADR handles sync/HTTP path

All ADRs Compiled 2026-05-22 from source/entities/adrs/ADR-025.yaml