# Migrating Towards Events Safely — Event-Driven Architecture & CQRS

Source: https://www.skillbyai.com/en/event-driven-architecture/o-evolve

> Introduce events into an existing synchronous system step by step.

## Incremental, reversible steps

Few teams start from a blank page. A safe path: first, publish **events alongside existing behaviour** using an outbox or CDC, without changing any consumer. Then move **non-critical side effects** (emails, analytics, search indexing) from synchronous calls to event consumers, one at a time, keeping the old path behind a feature flag until the new one is proven. Next, build **read models** from events where queries strain the main database. Only then consider moving core business steps to sagas. Throughout, keep a **catalogue of events** (names, owners, schemas, consumers), for example with AsyncAPI documents, so the system does not turn into an untracked web of topics. Run **shadow consumers** that process events but do not act, to compare results with the old path before switching.

## An AsyncAPI description of a channel

Documents who publishes what, like OpenAPI does for REST.

```yaml
asyncapi: 3.0.0
info:
  title: Orders events
  version: 1.2.0
channels:
  ordersPlaced:
    address: orders.placed
    messages:
      OrderPlaced:
        $ref: '#/components/messages/OrderPlaced'
operations:
  publishOrderPlaced:
    action: send
    channel:
      $ref: '#/channels/ordersPlaced'
components:
  messages:
    OrderPlaced:
      payload:
        type: object
        required: [orderId, customerId, totalMinor, currency]
        properties:
          orderId: { type: string }
          customerId: { type: string }
          totalMinor: { type: integer }
          currency: { type: string }
```

## Start with side effects nobody waits for

Moving confirmation emails or analytics to events gives early wins with low risk. Moving payment authorisation first is the opposite: high risk and hard to roll back.

**Quiz:** What is a low-risk first step when introducing events into an existing system?

- [ ] Rewrite every service as event-sourced
- [ ] Replace the database with a broker
- [x] Publish events alongside existing behaviour and move non-critical side effects to consumers
- [ ] Remove all synchronous APIs

*Answer:* Publish events alongside existing behaviour and move non-critical side effects to consumers. Additive, reversible steps let you learn and roll back without risking core flows.
