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 |
Related decisions¶
| 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