Receber por email
← Voltar para o catálogo

event-driven-architecture

Use esta skill ao projetar sistemas orientados a eventos, implementar event sourcing, aplicar padrões CQRS, selecionar message brokers ou raciocinar sobre consistência eventual. Ela é acionada em tarefas que envolvem Kafka, RabbitMQ, event stores, separação de comando-consulta, eventos de domínio, sagas, transações compensatórias, idempotência, ordenação de mensagens e qualquer arquitetura onde os componentes se comunicam assincronamente.

185estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add AbsolutelySkilled/AbsolutelySkilled

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/event-driven-architecture-absolutelyskilled/svg)](https://www.skillteca.com.br/skills/event-driven-architecture-absolutelyskilled)
#ai

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

When this skill is activated, always start your first response with the 🧢 emoji.

Event-Driven Architecture

A comprehensive guide to building systems where components communicate through events rather than direct calls. Event-driven architecture (EDA) decouples producers from consumers, enabling independent scaling, temporal decoupling, and resilience to downstream failures. This skill covers four core pillars: event sourcing (storing state as a sequence of events), CQRS (separating read and write models), message brokers (the transport layer), and eventual consistency (the consistency model that makes it all work). Agents use this skill to design, implement, and troubleshoot event-driven systems at any scale.

When to use this skill

Trigger this skill when the user:

  • Wants to implement event sourcing for an aggregate or service
  • Needs to separate read and write models using CQRS
  • Is choosing between Kafka, RabbitMQ, NATS, or other message brokers
  • Asks about eventual consistency, compensation, or saga patterns
  • Wants to design an event schema or event versioning strategy
  • Needs to handle idempotency in event consumers
  • Is debugging issues with message ordering, duplicate delivery, or consumer lag
  • Asks about domain events, integration events, or event-carried state transfer

Do NOT trigger this skill for:

  • Synchronous REST API design without an event component (use api-design)
  • General system design questions about load balancers, caches, or CDNs (use system-design)

Key principles

  1. Events are facts, not requests - An event records something that already happened

(OrderPlaced, PaymentReceived). It is immutable. Commands request something to happen (PlaceOrder). Never conflate the two. Events use past tense; commands use imperative.

  1. Design for at-least-once delivery - No message broker guarantees exactly-once

delivery in all failure scenarios. Design every consumer to be idempotent. Use deduplication keys (event ID + consumer ID) or make operations naturally idempotent (SET over INCREMENT).

  1. Own your events, share your contracts - The producing service owns the event

schema. Consumers must not dictate what goes in an event. Publish a versioned schema contract (Avro, Protobuf, or JSON Schema) so consumers can evolve independently.

  1. Separate the write model from the read model - CQRS lets you optimize writes for

consistency and reads for query performance independently. The write side validates business rules; the read side denormalizes for fast lookups. They connect through events.

  1. Embrace eventual consistency, but bound it - Eventual consistency is not "maybe

consistent." Define SLAs for propagation delay (e.g., "read model updated within 2 seconds of write"). Monitor consumer lag. Alert when the bound is breached.

Core concepts

Events are immutable records of state changes. A domain event captures a meaningful business occurrence within a bounded context (OrderPlaced). An integration event crosses context boundaries and should carry only the data consumers need - not the entire aggregate state. Event-carried state transfer includes enough data in the event so consumers never need to call back to the producer.

Event sourcing stores the current state of an entity as a sequence of events rather than a single mutable row. To get current state, replay all events for that aggregate from the event store. Snapshots periodically checkpoint state to avoid replaying the full history. The event store is append-only - never update or delete events. This gives a complete audit trail and enables temporal queries ("what was the order state at 3pm yesterday?").

CQRS (Command Query Responsibility Segregation) splits a service into a command side that handles writes and a query side that handles reads. The command side validates invariants and emits events. The query side subscribes to those events and builds denormalized read models (projections) optimized for specific queries. CQRS does not require event sourcing, and event sourcing does not require CQRS - but they pair naturally because the event log is the bridge between the two sides.

Message brokers are the transport layer. They sit between producers and consumers and handle routing, delivery guarantees, and backpressure. Key broker categories: log-based (Kafka, Redpanda) retain ordered, replayable event logs; queue-based (RabbitMQ, SQS) deliver messages to consumers and remove them after acknowledgment. Choose log-based when you need replay, ordering, and multiple consumer groups. Choose queue-based for simple task distribution and routing flexibility.

Eventual consistency means that after a write, all read replicas and projections will converge to the same state - but not instantly. The gap between write and convergence is the propagation delay. Sagas coordinate multi-service transactions: each step emits an event, and failure triggers compensating events that undo prior steps (e.g., PaymentFailed triggers OrderCancelled). Prefer choreography (services react to events) over orchestration (a central coordinator sends commands) for loosely coupled systems.

Common tasks

Implement event sourcing for an aggregate

Store all state changes as events. Rebuild current state by replaying them.

Event store schema (PostgreSQL example):

CREATE TABLE events (
  event_id     UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  aggregate_id UUID NOT NULL,
  aggregate_type VARCHAR(100) NOT NULL,
  event_type   VARCHAR(100) NOT NULL,
  event_data   JSONB NOT NULL,
  metadata     JSONB DEFAULT '{}',
  version      INTEGER NOT NULL,
  created_at   TIMESTAMPTZ NOT NULL DEFAULT now(),
  UNIQUE (aggregate_id, version)
);

Aggregate reconstruction:

def load_aggregate(aggregate_id: str) -> Order:
    events = event_store.get_events(aggregate_id)
    order = Order()
    for event in events:
        order.apply(event)
    return order
Use the UNIQUE constraint on (aggregate_id, version) for optimistic concurrency.
If two commands try to append at the same version, one fails - retry it.

Set up CQRS with separate read/write models

The command side validates and persists events. The query side projects events into denormalized views.

Command side: Receives commands, loads aggregate from event store, validates business rules, appends new events.

Query side: Subscribes to event stream, updates read-optimized projections (e.g., a materialized view in PostgreSQL, an Elasticsearch index, or a Redis hash).

Projection example:

class OrderSummaryProjection:
    def handle(self, event):
        if event.type == "OrderPlaced":
            db.upsert("order_summaries", {
                "order_id": event.data["order_id"],
                "customer": event.data["customer_name"],
                "total": event.data["total"],
                "status": "placed"
            })
        elif event.type == "OrderShipped":
            db.update("order_summaries",
                where={"order_id": event.data["order_id"]},
                set={"status": "shipped"})
Keep projections rebuildable. If a projection is corrupted, delete it and replay
all events from the store to reconstruct it from scratch.

Choose a message broker

| Requirement | Recommended broker | |---|---| | Ordered event log with replay | Kafka or Redpanda | | Simple task queue with routing | RabbitMQ | | Serverless / managed queue | AWS SQS + SNS | | Low-latency pub/sub | NATS | | Multi-protocol flexibility | RabbitMQ (AMQP, MQTT, STOMP) |

Kafka specifics: Topics are partitioned. Order is guaranteed only within a partition. Use the aggregate ID as the partition key to ensure all events for one entity land on the same partition in order. Consumer groups enable parallel consumption - each partition is read by exactly one consumer in a group.

**RabbitMQ

Compartilhar X LinkedIn