Receber por email
← Voltar para o catálogo

integration-architecture

This skill should be used when the user asks about "messaging patterns", "command vs event", "push vs pull", "message reliability", "at-least-once delivery", "idempotency", "transactional outbox", "saga pattern", "fire and forget", "retry strategy", "event-driven architecture", "message broker integration", "publish-subscribe", "request-reply", "backpressure", or when deciding how components commu

14estrelas
Atualizado há 2 meses

Ver no GitHub ↗ Licença: Apache-2.0

Como adicionar

/plugin marketplace add t1/tdder

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/integration-architecture/svg)](https://www.skillteca.com.br/skills/integration-architecture)

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

Integration Architecture

How components communicate across boundaries: message style, data flow direction, and failure handling.

This skill complements [Unfolding Architecture](../unfolding-architecture/SKILL.md), which covers the decision of whether to use messaging at all (Communication dimension, Levels 0→1→2). Once you've decided to communicate across boundaries, this skill guides how.

Tradeoff: Command vs. Event Messages

Commands couple sender to receiver: the sender knows who to call and what to ask for. Events invert the dependency: receivers must know the sender's domain to interpret what happened. In more complex messaging patters, when several, interdependent messages are sent, the dependency is even stricter: the sender of commands must know about the state of the receiver; with events it's the other way around. Neither is strictly better.

Prefer Commands when:

  • There is exactly one receiver
  • Sender needs confirmation the action was performed
  • Traceability and explicit flow matter
  • The operation is imperative ("do this")

Prefer Events when:

  • Multiple independent consumers react to the same thing
  • Adding consumers should not require changing the sender
  • Sender should not know about side effects
  • The message describes something that happened ("this occurred")

Key insight: Events don't remove coupling, they move it. The receiver now needs to understand the sender's context to react. This is worthwhile when senders change less often than the set of receivers.

When introducing cross-boundary communication, use AskUserQuestion with a code-based recommendation:

  • Question: "Should this be a command or an event?"
  • Options: Put the recommended option first with "(Recommended)". Use the option description

to explain why based on the code — e.g., "The method name orderCompleted and the lack of a return value suggest a notification, not a directive" or "There is exactly one receiver (PaymentService) that needs to confirm the action."

  • "Let's discuss" — elaborate on the trade-offs before deciding
  • If the code signals are ambiguous, don't recommend — present all options neutrally.

Request-Reply

A hybrid pattern: the sender sends a command and waits for a response, but communication is asynchronous (via a broker with a reply queue, not a direct method call). Useful when you need the decoupling benefits of messaging but the sender still requires a result.

Prefer Request-Reply when:

  • The sender needs a result but should not be coupled to the receiver's deployment
  • Temporal decoupling is needed (the reply may arrive later)
  • Load leveling or routing through a broker is required

Prefer direct commands when:

  • Latency matters and a synchronous call is acceptable
  • The reply queue infrastructure would add complexity without clear benefit

Tradeoff: Push vs. Pull

Who initiates data flow.

Prefer Pull when:

  • Consumer only needs data on-demand
  • Consumer controls timing and rate
  • Request/response is sufficient
  • Simpler infrastructure (HTTP, DB queries)

Prefer Push when:

  • Consumers need data as soon as it's available
  • Polling would create unnecessary load
  • Multiple consumers need the same data
  • Producer knows best when data is ready

Key insight: Push shifts backpressure responsibility to the consumer. Pull is simpler but can miss real-time needs or waste resources on empty polls.

Backpressure

When a producer pushes faster than a consumer can process, work piles up. Backpressure is how the consumer signals the producer to slow down (or how the system absorbs the mismatch).

Common strategies:

  • Bounded queues: reject or block when full — producer discovers the limit
  • Rate limiting: consumer controls ingestion rate explicitly
  • Credit-based flow: consumer grants the producer permission to send N messages per timeframe
  • Competing consumers: scale out consumers to match producer throughput

Choose a strategy before going to production with push-based messaging. Unbounded queues are not a strategy — they defer the problem until memory runs out.

Dimension: Reliability

How communication handles failures. This dimension progresses under pressure, following the unfolding principle: start at Level 0, unfold only when concrete problems force the change.

| Level | Style | Description | |-------|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 0 | Fire and forget | Send and assume success. No retries. Simple, appropriate when loss is acceptable or communication is in-process. | | 1 | Retry + idempotency | Retry on failure; receivers are idempotent so duplicates are harmless. At-least-once delivery. Techniques: deduplication (message IDs), upserts, deterministic operations. | | 2 | Transactional guarantees | Strongest guarantees, highest complexity. See techniques below. |

When choosing a reliability level, use AskUserQuestion with a code-based recommendation:

  • Question: "What reliability level does this communication need?"
  • Options: Put the recommended option first with "(Recommended)". Use the option description

to explain why based on the code — e.g., "This is an in-process call; failure means process crash anyway, so fire-and-forget is appropriate" or "This payment flow has business consequences on message loss; retry + idempotency is the minimum."

  • "Let's discuss" — elaborate on the trade-offs before deciding
  • If the code signals are ambiguous, don't recommend — present all options neutrally.

Unfold to Level 1 when:

  • Communication crosses process or network boundaries,

do transient failures (network blips, restarts) are to be expected

  • Message loss has business consequences

Do NOT unfold to Level 1 when:

  • Communication is in-process where failure = process crash anyway
  • The operation is naturally idempotent and loss is acceptable for the business

Unfold to Level 2 when:

  • Duplicates have business consequences that idempotency cannot absorb
  • An operation must atomically update local state AND send a message (outbox pattern)
  • Multiple services must coordinate a consistent outcome (saga)

Do NOT unfold to Level 2 when:

  • Idempotency is cheap to implement (prefer Level 1)
  • The operation is naturally idempotent (e.g., setting a value, not incrementing)
  • Only one service owns the data being changed

Level 2 Techniques

Transactional outbox: Instead of sending a message directly (which can fail independently of the local transaction), write the message to an outbox table in the same database transaction as the business data change. A separate process reads the outbox and publishes the messages. This guarantees that the local state change and the message are atomic — either both happen or neither does.

Saga: A sequence of local transactions across multiple services, each publishing an event or command that triggers the next step. If a step fails, compensating transactions undo the preceding steps. Sagas trade atomicity for availability — the system is eventually consistent, and you must design compensating actions for every step that can fail.

Testing Distributed Failures

Integration code fails in ways that unit tests for business logic never exercise: brokers restart, messages arrive out of order, schemas drift between producer and consumer, compensation logic triggers under unexpected conditions. The scopes below are independent — pick t

Compartilhar X LinkedIn