System Architecture
The microservices platform follows a distributed architecture with polyglot services communicating via gRPC/Connect and REST APIs, backed by PostgreSQL for data persistence and Traefik for edge routing.Service Directory
Go Microservices (connect-go)
All Go services use connect-go, a gRPC-compatible RPC framework that works over HTTP/1.1, HTTP/2, and gRPC protocols.Greeter Service
Port: 8080
Protocol Buffers:
Location:
Protocol Buffers:
greeter/v1/greeter.protoDemonstrates service-to-service calls and external API integration.Responsibilities:- Accept greeting requests
- Call Caller service for external API data
- Store greetings in PostgreSQL
- Return formatted response with external API status
greeter_dbLocation:
services/internal/greeter/Caller Service
Port: 8081
Protocol Buffers:
Location:
Protocol Buffers:
caller/v1/caller.protoHTTP client service for external API calls.Responsibilities:- Receive URL from other services
- Make HTTP requests to external APIs
- Return status code and response metadata
- Track call history in database
caller_dbLocation:
services/internal/caller/Gateway Service
Port: 8082
Protocol Buffers:
Location:
Protocol Buffers:
gateway/v1/gateway.protoAPI gateway integrating with custom language service.Responsibilities:- Route requests to custom-lang-service
- Transform REST responses
- Aggregate data from Node.js services
- Persist gateway metrics
gateway_dbLocation:
services/internal/gateway/Node.js Microservices (Express)
Auth Service
Port: 8090
Framework: Express 5JWT-based authentication service.Features:
Location:
Framework: Express 5JWT-based authentication service.Features:
- User registration with bcrypt password hashing
- JWT token generation and validation
- Login/signup endpoints at
/auth/* - Password strength validation
- Token expiration handling
auth_dbLocation:
node-services/auth-service/Tech Stack:express- Web frameworkjsonwebtoken- JWT handlingbcrypt- Password hashingpg- PostgreSQL client
Custom Lang Service
Port: 3000
Framework: Express 5Custom language processing service.Responsibilities:
Location:
Framework: Express 5Custom language processing service.Responsibilities:
- Process custom language requests
- Return localized responses
- Store language preferences
- Expose REST API for Gateway service
lang_dbLocation:
node-services/custom-lang-service/Communication Patterns
1. Frontend to Backend (connect-web)
The React frontend uses connect-query (TanStack Query + connect-web) for type-safe API calls.All frontend API code is generated from
.proto files via buf generate, ensuring type safety across the stack.2. Service-to-Service (connect-go)
Go services communicate using connect-go clients:services/internal/greeter/service.go
3. REST Integration
Gateway service calls Node.js services via REST:4. Protocol Buffers Schema
Example proto definition for Greeter service:proto/greeter/v1/greeter.proto
Changes to
.proto files require running buf generate to regenerate Go and TypeScript clients.Data Layer
PostgreSQL Architecture
Each service has its own database following the Database-per-Service pattern:| Service | Database Name | Purpose |
|---|---|---|
| Greeter | greeter_db | Store greeting records with external API metadata |
| Caller | caller_db | Track external API call history |
| Gateway | gateway_db | Gateway request/response logs |
| Auth | auth_db | User credentials and sessions |
| Custom Lang | lang_db | Language preferences and translations |
Database Initialization
Databases are created automatically viascripts/init-db.sh on first Docker Compose startup:
scripts/init-db.sh
Infrastructure Components
Traefik v3 (API Gateway)
Traefik acts as the edge router and API gateway with: Features:- Automatic service discovery via Docker labels
- HTTP/2 (h2c) support for connect-go services
- Middleware injection (CORS, auth, rate limiting)
- Request/response logging
- Health checks
docker-compose.yml):
- Docker Compose: http://localhost:30081
- Kubernetes: http://localhost:30081 (NodePort)
Observability Stack (Kubernetes Only)
When running withfull-bootstrap, you get:
Prometheus
Port: 30090
Metrics collection and alerting
Metrics collection and alerting
- Service metrics
- Go runtime metrics
- Node.js metrics
- Custom business metrics
Grafana
Port: 30300
Credentials: admin/adminVisualization and dashboards
Credentials: admin/adminVisualization and dashboards
- Pre-configured dashboards
- Service health monitoring
- Query Prometheus and Loki
Loki
Log aggregation system
- Centralized logging
- Log correlation with traces
- Efficient storage
- LogQL queries
Tempo
Distributed tracing backend
- OpenTelemetry integration
- End-to-end request tracing
- Service dependency mapping
- Latency analysis
docker-compose.yml
In local Docker Compose mode,
OTEL_EXPORTER_OTLP_ENDPOINT is set to "" to disable telemetry export.Deployment Models
Docker Compose (Local Development)
Use Case: Quick local testing without Kubernetes complexity. Architecture:- All services in a single
appbridge network - Traefik for routing
- Persistent PostgreSQL volume
- No observability stack
Kubernetes with Tilt (Cloud-Native Development)
Use Case: Develop and test in a Kubernetes environment locally. Architecture:- Kind cluster (local Kubernetes)
- Tilt for live reloading
- nixidy for manifest generation
- Optional observability stack
- Live code reloading without rebuilding containers
- Dependency management between services
- Log streaming from all pods
- Resource status dashboard at http://localhost:10350
Infrastructure as Code (nixidy)
Kubernetes manifests are generated from Nix modules:deploy/k8s/greeter.nix
Manifest generation requires files to be in Git staging. Run
git add <files> before gen-manifests.Security Considerations
Authentication
- JWT tokens with expiration
- bcrypt password hashing (cost factor 10)
- Auth middleware via Traefik
- Token validation on protected routes
Network Security
- Services isolated in container networks
- Traefik as single entry point
- CORS middleware configured
- Rate limiting enabled
Data Protection
- Database credentials via environment variables
- SQL injection prevention via parameterized queries
- Separate databases per service
- Connection pooling with pgx (Go) and pg (Node.js)
Development Best Practices
.envfiles in.gitignore- Pre-commit hooks for security scanning
- Dependency vulnerability checks
- Container scanning in CI
Directory Structure
Next Steps
Adding a New Service
Learn how to scaffold new Go or Node.js microservices
Protocol Buffers Guide
Master proto definitions and code generation
Testing Strategy
Unit, integration, and smoke testing patterns
CI/CD Pipeline
Understand the GitHub Actions workflow