Lab 15: Capstone — Distributed Service

Time: 45 minutes | Level: Advanced | Docker: docker run -it --rm --network=host golang:1.22-alpine sh

Overview

Build a complete production-ready microservice combining all advanced concepts:

  • SQLite via modernc.org/sqlite (pure Go, no CGO)

  • Redis caching with go-redis/v9

  • Circuit breaker with gobreaker

  • Structured logging with slog

  • Graceful shutdown (context + WaitGroup + SIGTERM)

  • Table-driven tests with testing

  • HTTP API with health/readiness endpoints


Step 1: Architecture Overview

┌─────────────────────────────────────────────────────────┐
│                   HTTP Server (:8080)                    │
│  GET /health    GET /ready    GET /products              │
└──────────────────────┬──────────────────────────────────┘

              ┌────────▼────────┐
              │  ProductService  │
              │  (domain logic)  │
              └────┬────────┬───┘
                   │        │
       ┌───────────▼──┐  ┌──▼──────────────┐
       │ Redis Cache  │  │ Circuit Breaker  │
       │ (go-redis)   │  │ (gobreaker)      │
       └──────────────┘  └──┬──────────────┘

                    ┌────────▼────────┐
                    │ SQLite (modernc) │
                    │ (pure Go, no CGO)│
                    └─────────────────┘

Step 2: Project Structure


Step 3: Domain Layer (domain.go)


Step 4: SQLite Adapter (db.go)


Step 5: Service Layer with Circuit Breaker


Step 6: HTTP Handler


Step 7: Table-Driven Tests


Step 8: Capstone — Complete Verified Run

Single-File Runnable Demo

📸 Verified Output (with Redis on port 16379):

📸 Verified Output (without Redis):


Summary — All Components Wired Together

Component
Library
Role

HTTP Server

stdlib net/http

API gateway

SQLite

modernc.org/[email protected]

Persistent store (no CGO)

Redis Cache

go-redis/v9

Read-through cache

Circuit Breaker

Failure isolation

Structured Logging

log/slog (Go 1.21 stdlib)

JSON logs

Graceful Shutdown

context + sync.WaitGroup

Zero-downtime deploy

Table Tests

stdlib testing

Validation coverage

Architecture Decisions:

  • Domain types have zero external dependencies

  • Redis is optional — service degrades gracefully without it

  • Circuit breaker protects SQLite from thundering herd on failures

  • sync.WaitGroup ensures all requests finish before shutdown

  • Table-driven tests cover all validation edge cases

Key Takeaways:

  • modernc.org/sqlite is pure Go — works on Alpine, no CGO needed

  • Cache-aside pattern: check cache → miss → DB → populate cache

  • Circuit breaker state machine: Closed → Open (on failures) → Half-Open → Closed

  • signal.Notify + server.Shutdown(ctx) is the idiomatic graceful shutdown pattern

  • log/slog with NewJSONHandler produces structured, parseable logs ready for Datadog/ELK

Last updated