Architecture Overview
tsdevstack uses a gateway-first architecture where all traffic flows through a central API gateway before reaching your services. This pattern provides consistent security, routing, and observability across all your APIs.
High-level architecture
Internet
│
▼
┌─────────────────────────────┐
│ Cloud Load Balancer │
│ • TLS termination │
│ • WAF rules │
│ • Health checks │
└─────────────┬───────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────────────────────────────────────┐
│ CDN / Bucket │ │ Private Network │
│(static assets)│ │ │
│ │ │ ┌─────────────────┐ ┌───────────────────┐ │
│ • SPA apps │ │ │ Kong Gateway │ │ Next.js Frontend │ │
│ • Edge cache │ │ │ (api.*) │ │ (example.com) │ │
│ │ │ │ • JWT, CORS │ │ • SSR container │ │
└───────────────┘ │ └────────┬────────┘ └───────────────────┘ │
│ │ │
│ ┌─────┴─────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌───────┐ ┌─────────┐ ┌───────┐ │
│ │ Auth │ │ Offers │ │ BFF │ │
│ │Service│ │ Service │ │ │ │
│ └───┬───┘ └────┬────┘ └───┬───┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌───────────────────────────────────────┐ │
│ │ Managed PostgreSQL │ │
│ │ • Private IP • Per-service DBs │ │
│ └───────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ Managed Redis │ │
│ │ • Rate limiting • Sessions │ │
│ └───────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ Secret Manager │ │
│ │ • JWT keys • DB credentials │ │
│ └───────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────┘
Every external request goes through Kong first. Kong handles authentication, validates tokens, applies rate limits, and then forwards validated requests to your services. Your services never handle raw external traffic directly.
Core components
API Gateway (Kong)
Kong is the front door to your application. It handles:
- Routing - Maps URL paths to backend services (e.g.,
/auth/v1/*goes to auth-service) - Authentication - Validates JWT tokens before requests reach your services
- Rate limiting - Prevents abuse with configurable request limits (stored in Redis)
- CORS - Manages cross-origin requests for browser clients
- Header transformation - Strips spoofed headers, adds trusted headers
In tsdevstack, Kong configuration is generated automatically from your OpenAPI specs. When you add an endpoint to a service, Kong routing is updated to match.
Backend services
Services are NestJS applications that contain your business logic. Each service:
- Handles a specific domain (auth, users, products, etc.)
- Has its own database (when needed)
- Exposes a REST API with OpenAPI documentation
- Runs as an independent container
- Is only reachable through Kong (not directly from the internet)
- Has its own auth guards for defense in depth
Services don't know about each other's internals. They communicate through well-defined APIs.
While Kong handles primary authentication at the gateway level, services also implement their own auth guards. This defense-in-depth approach means authentication is verified at multiple layers, protecting against misconfiguration or gateway bypass scenarios.
Frontend (optional)
The included Next.js frontend handles:
- Server-side rendering for SEO and performance
- Secure cookie-based authentication (no tokens in localStorage)
- API routes that proxy requests to Kong
Databases
PostgreSQL is the primary data store. Each service that needs persistence gets its own database, keeping data isolated and services independent.
Redis provides fast caching and is used for:
- Rate limiting counters (distributed across Kong instances)
- Session data
- General application caching
Request flow
Here's what happens when a user makes an API request:
For authenticated requests, Kong extracts user information from the JWT and passes it to services via trusted headers. Services can rely on these headers without re-validating the token.
How local mirrors cloud
One of tsdevstack's core design principles is that local development should work exactly like production. The same architecture runs in both environments:
The key differences are in networking and scale:
- Local: All containers run on your machine, connected via Docker network
- Cloud: Services run in isolated networks, only reachable through the gateway
Your code doesn't change between environments. Configuration (database URLs, API endpoints) comes from secrets that tsdevstack manages per environment.
Service isolation
In the cloud architecture, backend services are not directly accessible from the internet:
This isolation means:
- Services only accept requests from Kong
- External attackers cannot bypass authentication
- Internal service-to-service calls use separate API keys
Locally, services are directly accessible for convenience - you can hit endpoints through Postman or curl without going through Kong. The network isolation only applies in cloud environments.
Technology choices
What's generated vs. what you write
tsdevstack generates infrastructure and configuration. You write business logic.
Generated by tsdevstack:
- Application scaffolding (NestJS services pre-configured with @tsdevstack/nest-common)
- Kong configuration and routing
- Docker Compose for local development
- Database connection configuration
- OpenAPI specs from your decorators
- Terraform infrastructure code
- HTTP client packages with DTOs
Written by you:
- Service endpoints and controllers
- Database models and migrations
- Business logic and validation
- Frontend pages and components