Chapter 1. Embracing event-driven architectures
1.1. The truth about monoliths
1.1.1. Anatomy of a typical monolith
1.1.2. It's not all bad 1.1.3. When monoliths become the business constrictor knot
1.1.4. Using event-driven architectures to move away from a monolith
1.2. What are microservices and how do they relate to event-driven
1.3. SOA, microservice, and event-driven architectures
1.4. The promise of event-driven microservices
1.5. When should you use event-driven microservices?
1.6. Overview of the challenges in event-driven architectures 1.7. Summary
Chapter 2. Moving from a monolith to an event-driven architecture
2.1. Is migrating to an event-driven architecture your best option?
2.2. How to decide where to start
2.3. Using an event-driven approach to migrate data
2.4. Using change data capture (CDC)
2.4.1. Event-driven and change data capture (CDC), a real-world example 2.5. Event-driven as a source of truth for both systems
2.6. Managing dependencies between the two systems
2.6.1. Dependency from new event-driven services to the monolith 2.6.2. Dependency from the monolith to new event-driven services
2.7. Gradually moving traffic
2.8. Two-way synchronization and living with two sources of truth
2.9. Summary
Chapter 3. Defining an event-driven microservice and its boundaries
3.1. Building event-driven microservices
3.1.1. Durable vs. ephemeral message brokers and GDPR 3.1.2. Message types
3.1.3. When to use documents over events
3.1.4. Common event-driven messaging patterns
3.1.5. Event-driven service topologies
3.1.6. Common event-driven pitfalls and anti-patterns
3.2. Organizing event-driven microservice boundaries
3.3. Brief and practical introduction to domain-driven design and bounded contexts 3.4. The impact of aggregate size and common pitfalls
3.5. Request-driven vs. event-driven services
3.6. Adding functionality to an existing microservice vs. creating a new one
3.7. Summary
Chapter 4. Event-driven structural patterns and high-level processes
4.1. The challenges of transactional consistency in distributed systems
4.1.1. Why abandon a monolithic database in the first place? 4.1.2. The limitations of distributed transactions
4.1.3. Managing multi-step processes with Sagas
4.2. Event-driven orchestration pattern 4.3. Event-driven choreography pattern
4.4. Orchestration, choreography, or both?
4.5. Data retrieval in event-driven architectures and associated patterns
4.5.1. CQS, CQRS and when to use them
4.5.2. The different flavors of CQRS
4.5.3. When and how to use event sourcing
4.5.4. Using command sourcing and its applicability 4.6. Building multiple read models
4.7. The pitfall of microservice spaghetti architectures and how to avoid it
4.8. Summary
Chapter 5. How to manage eventual consistency
5.1. The impacts of eventual consistency and the need for alignment with the business
5.2. Using event schema to leverage eventual consistency
5.3. Applying domain boundaries to leverage eventual consistency 5.4. Event versioning to manage delays
5.5. Saving state to avoid eventual consistency
5.6. End-to-end argument: a real-world use case
5.7. For most use cases, it's not eventual if nobody notices
5.7.1. Autoscaling use case with Prometheus and Kafka
5.8. Tradeoffs of each solution
5.9. Summary Chapter 6. Dealing with event-driven concurrency and out of order messages
6.1. Why is concurrency different in a monolith from an event-driven arc