🏗️ Architecture Patterns

Macro architecture

PatternUse whenWatch out for
Layered monolithTiny appsBig ball of mud
Modular monolithDefault for new productsNeeds module boundaries enforced (ArchUnit, Spring Modulith)
MicroservicesMultiple teams, independent scaling/deploysDistributed-systems tax: network, consistency, ops
Event-drivenDecoupling, fan-out, audit, async workflowsEventual consistency, debugging, schema evolution
ServerlessSpiky workloads, glueCold starts, vendor lock-in, limits
Cell-basedVery large scale, blast-radius isolationRouting, operational complexity
Space-based / in-memory gridExtreme read/write loadsComplexity

Inside a service

  • Hexagonal (ports & adapters) / Clean Architecture: domain in the center, frameworks at the edges
  • DDD tactical: entities, value objects, aggregates (consistency boundary!), domain events, repositories
  • Vertical slice architecture: organize by feature, not by layer

Integration & data patterns

  • Transactional outbox (+ CDC via Debezium) to publish events reliably
  • Saga: choreography vs orchestration; compensating actions
  • CQRS: separate write model and read models (projections)
  • Event sourcing: state = fold(events); snapshots; when it’s worth it (rarely)
  • Idempotent consumer / inbox pattern
  • API composition / BFF (backend for frontend)
  • Strangler fig (incremental migration from a monolith)
  • Anti-corruption layer
  • Database per service vs shared DB
  • Durable execution (Temporal) as an alternative to hand-rolled sagas

Resilience patterns (Release It!)

Timeouts · retries with exponential backoff + jitter · circuit breaker · bulkhead · rate limiting · load shedding · fallback/graceful degradation · health checks · backpressure · idempotency keys

Deployment patterns

Blue/green · canary · rolling · feature flags (OpenFeature) · dark launches · expand/contract DB migrations

🧪 Labs (🟢 warm-up → 🟡 core → 🔴 hard → ⚫ boss)

  • 🟡 Spring Modulith boundaries + ArchUnit rules in orbit-api
  • 🔴 Outbox → Debezium → Kafka with an inbox dedupe on the consumer
  • 🔴 Orchestrated saga with compensation (UC3); then port it to Temporal and compare
  • ⚫ Rebuild the run-search read model from zero by replaying Kafka (CQRS rebuild)

🧠 Cognitive tasks

  • Trade-off debate: event sourcing for runs vs a state table + audit log
  • Pre-mortem: 10 ways the saga leaves inconsistent state

🛰️ Orbit integration

  • Hexagonal engine core; CQRS run search; a strangler-fig split of orbit-api later

Go deeper

Resources

  • Fundamentals of Software Architecture 2e (Richards & Ford) ⭐
  • Software Architecture: The Hard Parts (Ford et al.) ⭐
  • Microservices Patterns (Richardson) + microservices.io ⭐
  • Building Microservices 2e + Monolith to Microservices (Newman)
  • Learning Domain-Driven Design (Khononov) · Domain-Driven Design Distilled (Vernon)
  • Enterprise Integration Patterns (Hohpe & Woolf): reference
  • A Philosophy of Software Design (Ousterhout) ⭐: code-level design thinking