# Service Template Architecture This document describes the architecture of a single microservice built from this template and how it integrates with the GoodGo microservices platform. ## Overview This template provides a complete, production-ready foundation for building individual microservices with: - **Security**: Authentication, authorization, input validation, and security headers - **Observability**: Comprehensive logging, metrics, tracing, and health checks - **Data Management**: Repository pattern, database migrations, and seeding - **API Documentation**: OpenAPI/Swagger documentation with interactive UI - **Error Handling**: Structured error responses with proper HTTP status codes - **Docker Support**: Multi-stage builds and production optimization **Important Context**: This template represents a **single microservice**. For platform-level deployment and orchestration, services are registered in `deployments/local/docker-compose.yml` and routed through the Traefik API Gateway configured in `infra/traefik/`. --- # Part 1: Single Service Architecture (Internal) This section describes the internal architecture of a single microservice built from this template. ## Internal Service Components ```mermaid graph TD Request[HTTP Request] -->|From Traefik| Middleware[Middleware Chain] subgraph SingleService[Single Service Boundary] Middleware --> Correlation[Correlation ID Middleware] Correlation --> Auth[Authentication Middleware] Auth --> Validation[Validation Middleware] Validation --> Error[Error Handler] Error --> Logger[Request Logger] Logger --> Metrics[Metrics Collector] Metrics --> Router[Router Layer] Router --> Controller[Controller Layer] Controller --> Service[Service Layer] Service --> Repository[Repository Layer] Repository --> Database[(PostgreSQL)] Service --> Cache[(Redis)] Service -.->|Health Status| Health[Health Checks] Service -.->|API Docs| OpenAPI[OpenAPI/Swagger] end Service -.->|Metrics| Prometheus[Prometheus] Service -.->|Traces| Jaeger[Jaeger] style Correlation fill:#e1f5fe style Auth fill:#f3e5f5 style Validation fill:#e8f5e8 style Error fill:#fff3e0 style Logger fill:#f3e5f5 style Metrics fill:#e8f5e8 ``` ## Layer Architecture ### Middleware Chain The middleware chain processes every incoming request in order: 1. **Correlation Middleware**: Generates/propagates correlation and request IDs 2. **Authentication Middleware**: Validates JWT tokens (optional for public routes) 3. **Validation Middleware**: Sanitizes and validates input data with Zod schemas 4. **Error Handler**: Catches and formats errors into structured responses 5. **Logger Middleware**: Logs request/response with correlation IDs 6. **Metrics Middleware**: Collects Prometheus metrics (duration, status, payload size) ### Controller Layer - Handles HTTP requests and responses - Orchestrates service layer calls - Formats API responses - Wraps async handlers for error propagation ### Service Layer - Contains pure business logic - Independent of HTTP transport - Orchestrates repository calls - Implements caching strategies - Throws domain-specific errors ### Repository Layer - Abstracts database operations - Uses Prisma ORM for type-safe queries - Implements repository pattern - Provides consistent error handling - Supports transactions ## Request Flow 1. **Request Entry**: - Client sends HTTP request to ingress/load balancer - Request includes optional correlation ID header (`x-correlation-id`) 2. **Correlation Middleware**: - Generates or propagates correlation ID for request tracing - Adds request ID for unique request identification - Sets correlation headers on response 3. **Security Middleware**: - **Authentication**: Validates JWT tokens (optional for public routes) - **Authorization**: Checks user roles and permissions - **Rate Limiting**: Prevents abuse with Redis-backed rate limiting - **Helmet**: Secures HTTP headers 4. **Validation Middleware**: - Sanitizes input data (trimming, normalization) - Validates request data using Zod schemas - Returns structured validation errors 5. **Router & Controller**: - Routes request to appropriate controller - Controller orchestrates business logic execution - Input validation and response formatting 6. **Service Layer**: - Contains pure business logic - Independent of HTTP transport layer - Orchestrates data access and external service calls 7. **Repository Layer**: - Implements repository pattern for data access - Abstracts database operations with Prisma ORM - Provides consistent error handling 8. **Response & Observability**: - Formats structured JSON responses - Records comprehensive metrics (duration, errors, payload sizes) - Logs with correlation IDs for distributed tracing - Sends traces to Jaeger if enabled ## Architecture Patterns ### Repository Pattern ```typescript // Base repository with common CRUD operations class BaseRepository { async findById(id: string): Promise async create(data: CreateInput): Promise async update(id: string, data: UpdateInput): Promise // ... more common methods } // Specific repository extends base class FeatureRepository extends BaseRepository { async findByName(name: string): Promise async findByTags(tags: string[]): Promise // ... feature-specific methods } ``` ### Middleware Chain ```typescript // Request processing pipeline app.use(correlationMiddleware()); // Add correlation IDs app.use(authenticate()); // JWT validation app.use(authorize('admin')); // Role checking app.use(validateDto(schema)); // Input validation app.use(errorHandler); // Error handling ``` ### Error Handling ```typescript // Custom error classes class NotFoundError extends HttpError { constructor(resource: string) { super(`${resource} not found`, 404, 'NOT_FOUND'); } } // Usage in services if (!feature) { throw new NotFoundError('Feature'); } ``` ### Dependency Injection ```typescript // Constructor injection for testability export class FeatureService { constructor(private repository: IRepository) {} async create(data: CreateFeatureInput): Promise { return this.repository.create(data); } } ``` ## Best Practices ### Code Organization - **Separation of Concerns**: Clear boundaries between layers (Controller → Service → Repository) - **Single Responsibility**: Each class/method has one clear purpose - **Dependency Injection**: Constructor injection for better testability - **Error Boundaries**: Proper error handling at each layer ### Security - **Input Validation**: All inputs validated with Zod schemas - **Authentication**: JWT tokens with proper expiration - **Authorization**: Role-based access control (RBAC) - **Rate Limiting**: Distributed rate limiting with Redis - **Security Headers**: Helmet.js for HTTP security headers ### Observability - **Structured Logging**: Consistent log format with correlation IDs - **Metrics**: Comprehensive Prometheus metrics - **Tracing**: Distributed tracing with Jaeger - **Health Checks**: Liveness and readiness probes - **Correlation IDs**: Request tracing across service boundaries ### Error Handling - **Custom Error Classes**: Specific error types for different scenarios - **HTTP Status Mapping**: Proper status codes for different error types - **Structured Responses**: Consistent error response format - **Operational Errors**: Clear distinction between programming and operational errors ### Testing - **Unit Tests**: Test individual functions and classes - **Integration Tests**: Test component interactions - **E2E Tests**: Test complete request/response cycles - **Test Utilities**: Shared test helpers and mocks - **Coverage Goals**: >70% code coverage target ### Docker & Deployment - **Multi-stage Builds**: Optimized for production image size - **Security**: Non-root users, minimal attack surface - **Health Checks**: Container health monitoring - **Compose Files**: Development, testing, and production configurations - **Resource Limits**: Proper CPU and memory constraints ## Configuration Management ### Environment Variables - **Typed Configuration**: Zod schemas for env validation - **Default Values**: Sensible defaults for development - **Override Support**: `.env.local` overrides `.env` - **Documentation**: Comprehensive env variable documentation ### Feature Flags - **Runtime Configuration**: Database-backed feature flags - **Admin Control**: Admin API for feature management - **Gradual Rollout**: Enable/disable features without deployment - **Audit Trail**: Track feature flag changes ## API Design ### RESTful Conventions - **Resource Naming**: Plural nouns for resource endpoints - **HTTP Methods**: GET, POST, PUT, DELETE, PATCH appropriately - **Status Codes**: Proper HTTP status codes for all responses - **Content Negotiation**: JSON responses with proper content-type ### Response Format ```json { "success": true, "data": { ... }, "message": "Operation completed successfully", "timestamp": "2024-01-01T00:00:00.000Z" } ``` ### Error Responses ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Validation failed", "details": [...] }, "timestamp": "2024-01-01T00:00:00.000Z" } ``` ## Development Workflow ### Local Development 1. **Setup Infrastructure**: `docker-compose up -d` 2. **Install Dependencies**: `pnpm install` 3. **Database Setup**: `pnpm prisma migrate dev && pnpm prisma db seed` 4. **Start Development**: `pnpm dev` 5. **Run Tests**: `pnpm test` ### Testing Strategy 1. **Unit Tests**: Test individual functions and classes 2. **Integration Tests**: Test middleware chains and service interactions 3. **E2E Tests**: Test complete API workflows 4. **Performance Tests**: Load testing and performance validation ### Deployment Pipeline 1. **Linting**: Code quality checks with ESLint and Prettier 2. **Testing**: Full test suite execution (unit, integration, E2E) 3. **Security Scanning**: Dependency audit, SAST, and container scanning 4. **Build**: Multi-stage Docker image creation with security scanning 5. **Deploy**: Container orchestration deployment with health checks 6. **Verification**: Automated post-deployment health and performance verification --- # Part 2: Platform Integration (External) This section describes how a service built from this template integrates with the GoodGo microservices platform. ## Platform Architecture ```mermaid graph TD Client[Client / Browser] --> Traefik[Traefik API Gateway] subgraph Platform[GoodGo Microservices Platform] Traefik --> AuthService[Auth Service] Traefik --> YourService[Your Service from Template] Traefik --> OtherServices[Other Services...] YourService --> SharedDB[(Shared PostgreSQL)] YourService --> SharedRedis[(Shared Redis)] AuthService -.->|JWT Validation| YourService YourService -.->|Inter-Service Calls| OtherServices end subgraph Observability[Observability Stack] Prometheus[Prometheus] Grafana[Grafana] Jaeger[Jaeger] Loki[Loki] end YourService -.->|Metrics| Prometheus YourService -.->|Traces| Jaeger YourService -.->|Logs| Loki Prometheus --> Grafana style Traefik fill:#ffecb3 style YourService fill:#e1f5fe ``` ## Service Discovery & Registration Services are registered with Traefik via Docker labels in `deployments/local/docker-compose.yml`: ```yaml services: your-service: build: context: ../.. dockerfile: services/your-service/Dockerfile labels: # Enable Traefik for this service - "traefik.enable=true" # Define routing rule - "traefik.http.routers.your-service.rule=PathPrefix(`/api/v1/your-service`)" # Specify service port - "traefik.http.services.your-service.loadbalancer.server.port=5002" # Health check configuration - "traefik.http.services.your-service.loadbalancer.healthcheck.path=/health/live" - "traefik.http.services.your-service.loadbalancer.healthcheck.interval=10s" ``` ## Shared Infrastructure ### Traefik API Gateway (infra/traefik/) - **Location**: `infra/traefik/` - Platform-level configuration - **Static Config**: `traefik.yml` - Entry points, providers, API dashboard - **Dynamic Config**: `dynamic/middlewares.yml`, `dynamic/routes.yml` - **Features**: Load balancing, rate limiting, SSL/TLS, CORS, security headers ### PostgreSQL Database - **Shared or Isolated**: Can be shared database with schema isolation or separate databases - **Connection**: Via `DATABASE_URL` environment variable - **Migrations**: Managed per-service with Prisma ### Redis Cache - **Shared Instance**: Common Redis instance for all services - **Connection**: Via `REDIS_URL` or `REDIS_HOST`/`REDIS_PORT` - **Use Cases**: Caching, rate limiting, session storage ### Observability Stack (infra/observability/) - **Prometheus**: Metrics collection from all services - **Grafana**: Visualization and dashboards - **Jaeger**: Distributed tracing - **Loki**: Log aggregation ## Inter-Service Communication ### HTTP/REST Communication Services communicate via HTTP through Traefik or direct service-to-service calls: ```typescript // Example: Calling another service const response = await fetch('http://auth-service:5001/api/v1/users/validate', { headers: { 'Authorization': `Bearer ${token}`, 'X-Correlation-ID': correlationId } }); ``` ### Authentication Flow 1. Client authenticates with Auth Service 2. Auth Service issues JWT token 3. Client includes JWT in requests to other services 4. Services validate JWT using `@goodgo/auth-sdk` 5. Services extract user info from validated token --- # Part 3: Deployment Context This section explains how to deploy a service built from this template to the platform. ## Adding Service to Platform ### Step 1: Create Service from Template ```bash # Use the create-service script ./scripts/utils/create-service.sh my-new-service # Or manually copy the template cp -r services/_template services/my-new-service ``` ### Step 2: Register in deployments/local/docker-compose.yml Add your service to the platform compose file: ```yaml services: my-new-service: build: context: ../.. dockerfile: services/my-new-service/Dockerfile container_name: my-new-service-local environment: - NODE_ENV=development - PORT=5003 - DATABASE_URL=${DATABASE_URL} - REDIS_HOST=redis - REDIS_PORT=6379 - JWT_SECRET=${JWT_SECRET} - SERVICE_NAME=my-new-service - API_VERSION=v1 depends_on: redis: condition: service_healthy networks: - microservices-network labels: - "traefik.enable=true" - "traefik.http.routers.my-new-service.rule=PathPrefix(`/api/v1/my-new-service`)" - "traefik.http.services.my-new-service.loadbalancer.server.port=5003" ``` ### Step 3: Configure Traefik Routes (Optional) For advanced routing, add to `infra/traefik/dynamic/routes.yml`: ```yaml http: routers: my-new-service: rule: "PathPrefix(`/api/v1/my-new-service`)" service: my-new-service middlewares: - secure-headers - cors - compress ``` ### Step 4: Start the Platform ```bash cd deployments/local docker-compose up -d ``` ### Step 5: Access Your Service - **API**: http://localhost/api/v1/my-new-service - **Health**: http://localhost/api/v1/my-new-service/health - **API Docs**: http://localhost/api/v1/my-new-service/api-docs - **Traefik Dashboard**: http://localhost:8080 ## Environment Configuration Services inherit environment variables from: 1. **Platform Level**: `deployments/local/.env.local` 2. **Service Level**: Service-specific environment in docker-compose.yml 3. **Defaults**: Service's `.env.example` for development ## Operational Excellence ### Incident Response 1. **Detection**: Automated monitoring alerts 2. **Assessment**: Incident severity classification 3. **Communication**: Stakeholder notification 4. **Investigation**: Root cause analysis 5. **Resolution**: Fix deployment and verification 6. **Post-mortem**: Incident review and improvement ### Capacity Planning - **Resource Monitoring**: Track CPU, memory, disk, and network usage - **Performance Benchmarks**: Regular performance testing - **Scaling Triggers**: Automated scaling based on metrics - **Cost Optimization**: Right-sizing resources ### Compliance & Security - **Security Audits**: Regular security assessments - **Compliance Checks**: GDPR, HIPAA, SOC2 compliance - **Data Encryption**: At-rest and in-transit encryption - **Access Controls**: Least privilege access principles