---
term: 'Padrão Pub/Sub (Publicação-Assinatura)'
seoTitle: 'Padrão Pub/Sub Explicado: Tópicos, Brokers, Garantias de Entrega'
headline: 'O que é o padrão Pub/Sub (publicação-assinatura)?'
slug: padrao-pub-sub
category: api-realtime
shortDefinition: 'Pub/sub é um padrão de mensageria em que publicadores enviam mensagens a tópicos em um broker, e cada assinante do tópico recebe uma cópia.'
relatedTerms:
  - event-driven-architecture
  - websockets-real-time-sync
  - real-time-live-queries
  - sse-vs-websockets-vs-polling
contrastsWith:
  - webhooks
aboutTerms:
  - 'Publicador (Publisher)'
  - 'Assinante (Subscriber)'
  - 'Tópico'
  - 'Broker de Mensagens'
faq:
  - question: 'O que é pub/sub em termos simples?'
    answer: 'Um padrão de mensageria em que remetentes (publicadores) postam mensagens em tópicos nomeados em um broker, e cada componente que assinou aquele tópico recebe a própria cópia — publicadores e assinantes nunca sabem uns dos outros. Pense em transmissão de rádio: a estação transmite numa frequência; quem sintonizar, ouve.'
  - question: 'Qual a diferença entre pub/sub e fila de mensagens?'
    answer: 'Uma fila distribui trabalho; pub/sub o duplica. Em uma fila, cada mensagem é consumida por exatamente um worker — a ferramenta para espalhar jobs por um pool. No pub/sub, cada assinante do tópico recebe uma cópia — a ferramenta para transmitir eventos a interessados independentes.'
  - question: 'Qual a diferença entre pub/sub e o padrão observer?'
    answer: 'Observer é in-process: o sujeito guarda referências diretas aos observadores e normalmente os chama de forma síncrona. Pub/sub insere um broker entre as partes, deixando-as totalmente desacopladas, tipicamente assíncronas e capazes de viver em processos, linguagens e deploys diferentes. Um é um padrão de projeto dentro de um app; o outro é uma arquitetura entre sistemas.'
  - question: 'O que é um tópico no pub/sub?'
    answer: 'Um canal lógico nomeado que categoriza mensagens: publicadores endereçam o tópico, e o broker entrega cada mensagem a todos os assinantes daquele tópico. A filtragem pode ser por tópico (assinar pelo nome, muitas vezes hierarquicamente — orders.*) ou por conteúdo, em que o broker compara atributos da mensagem.'
  - question: 'Quais garantias de entrega o pub/sub oferece?'
    answer: 'Três níveis. At-most-once: dispara e esquece — rápido, pode perder mensagens. At-least-once: tenta de novo até confirmar — o padrão comum, gera duplicatas ocasionais. Exactly-once: deduplicação mais coordenação — caro, restrito e impossível de garantir de ponta a ponta no caso geral. A postura prática: entrega at-least-once com handlers idempotentes.'
  - question: 'O pub/sub garante a ordem das mensagens?'
    answer: 'Não por padrão — as mensagens se espalham para assinantes paralelos, e ordem global briga com paralelismo. Brokers conseguem ordenar dentro de uma partição ou chave de ordenação, ao custo de throughput. O design robusto assume ordem apenas onde ela foi explicitamente configurada e escreve handlers que toleram chegada fora de ordem.'
  - question: 'Kafka é pub/sub?'
    answer: 'Sim, com um detalhe: o Apache Kafka implementa a semântica de publicação-assinatura sobre um commit log particionado, durável e com replay. Dentro de um consumer group ele se comporta como fila (cada mensagem vai a um membro); entre groups, como pub/sub (cada group recebe uma cópia) — por isso costuma ser chamado de event streaming.'
  - question: 'Quando não usar pub/sub?'
    answer: 'Quando quem chama precisa de uma resposta imediata (request-response), quando operações precisam ser atômicas entre produtor e consumidores (um broker não entra em uma transação — veja o padrão Saga), quando ordem global estrita é obrigatória, ou quando o sistema é pequeno o bastante para um broker adicionar mais superfície operacional do que remove.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'Publish-Subscribe Channel — Enterprise Integration Patterns'
    url: 'https://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.html'
  - name: 'MQTT 5.0 specification — OASIS'
    url: 'https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html'
  - name: 'Apache Kafka documentation — design'
    url: 'https://kafka.apache.org/documentation/#design'
  - name: 'What do you mean by "Event-Driven"? — Martin Fowler'
    url: 'https://martinfowler.com/articles/201701-event-driven.html'
cta:
  title: 'Publique salvando, assine consultando'
  text: 'As Live Queries do Back4app são pub/sub na borda: qualquer cliente assina uma query como seu tópico, qualquer escrita publica para todos os assinantes correspondentes — broker, fan-out e permissões rodam por conta da plataforma.'
  linkText: 'Comece grátis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-08-24'
translationKey: pub-sub-pattern
---

**Pub/sub é um padrão de mensageria em que publicadores enviam mensagens a tópicos em um broker, e cada assinante do tópico recebe uma cópia.** Todo o seu valor está no que as partes *não* sabem: publicadores nunca descobrem quem está ouvindo, assinantes nunca descobrem quem enviou — a indireção do broker os desacopla no espaço (sistemas diferentes), no tempo (assinantes podem estar offline) e na sincronização (o publish retorna imediatamente). Adicione assinantes sem tocar nos publicadores; esse é o superpoder discreto do padrão.

## Principais pontos

| Pergunta | Resposta |
| --- | --- |
| O elenco | Publicador → mensagem → tópico → broker → assinantes (cada um recebe uma cópia) |
| vs. uma fila | Uma fila *distribui* o trabalho a um consumidor; pub/sub o *duplica* para todos |
| vs. observer | Observer é in-process e síncrono; pub/sub tem broker e é assíncrono |
| A postura padrão | Entrega at-least-once + handlers idempotentes |
| As letras miúdas | Sem respostas, sem ordem por padrão, sem transações atômicas através do broker |

## O padrão em código

Toda API de pub/sub se reduz a dois verbos, seja qual for o broker:

```js
// Assinantes — registram interesse em um tópico
broker.subscribe('orders.paid', (msg) => fulfill(msg));   // serviço A
broker.subscribe('orders.paid', (msg) => notifyUser(msg)); // serviço B — sua própria cópia

// Publicador — dispara e esquece
broker.publish('orders.paid', { orderId: 'o-1187' });
// O publicador nunca descobre quem recebeu — nem se alguém recebeu.
```

A mesma forma na borda do cliente, onde uma assinatura de live query é o tópico e uma escrita no banco de dados é o publish:

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// Pub/sub at the edge: live queries subscribe, saves publish
// Subscriber — register interest in a topic
const topic = new Parse.Query('Event');
topic.equalTo('topic', 'orders');
const sub = await topic.subscribe();
sub.on('create', (event) => handle(event.get('payload')));

// Publisher — fire and forget; no knowledge of subscribers
const event = new Parse.Object('Event');
event.set('topic', 'orders');
event.set('payload', { orderId: 'o-1187', status: 'paid' });
await event.save();
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// Pub/sub at the edge: live queries subscribe, saves publish
// Subscriber — register interest in a topic
final liveQuery = LiveQuery();
final topic = QueryBuilder<ParseObject>(ParseObject('Event'))
  ..whereEqualTo('topic', 'orders');
final sub = await liveQuery.client.subscribe(topic);
sub.on(LiveQueryEvent.create, (event) => handle(event.get('payload')));

// Publisher — fire and forget; no knowledge of subscribers
final event = ParseObject('Event')
  ..set('topic', 'orders')
  ..set('payload', {'orderId': 'o-1187', 'status': 'paid'});
await event.save();
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// Pub/sub at the edge: live queries subscribe, saves publish
// Subscriber — register interest in a topic
let topic = Event.query("topic" == "orders")
let sub = try await topic.subscribe()
sub.handleEvent { _, e in
    if case .created(let event) = e { handle(event.payload) }
}

// Publisher — fire and forget; no knowledge of subscribers
var event = Event()
event.topic = "orders"
event.payload = ["orderId": "o-1187", "status": "paid"]
try await event.save()
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// Pub/sub at the edge: live queries subscribe, saves publish
// Subscriber — register interest in a topic
val client = ParseLiveQueryClient.Factory.getClient()
val topic = ParseQuery.getQuery<ParseObject>("Event")
topic.whereEqualTo("topic", "orders")
val sub = client.subscribe(topic)
sub.handleEvent(SubscriptionHandling.Event.CREATE) { _, event ->
    handle(event.getJSONObject("payload"))
}

// Publisher — fire and forget; no knowledge of subscribers
val event = ParseObject("Event")
event.put("topic", "orders")
event.put("payload", JSONObject(mapOf("orderId" to "o-1187", "status" to "paid")))
event.save()
```

## Como o pub/sub funciona

```mermaid
flowchart LR
  accTitle: Fluxo de mensagens publicação-assinatura através de um broker
  accDescr: Um publicador envia uma mensagem a um tópico nomeado em um broker de mensagens. O broker compara o tópico com as assinaturas registradas e entrega uma cópia independente da mensagem a cada assinante, que confirma o processamento separadamente.
  P["Publicador<br/>(dispara e esquece)"] -->|"publish(orders.paid, msg)"| T["Broker<br/>tópico: orders.paid"]
  T -->|"cópia 1"| S1["Assinante A<br/>fulfillment"]
  T -->|"cópia 2"| S2["Assinante B<br/>notificações"]
  T -->|"cópia 3"| S3["Assinante C<br/>analytics"]
```

O broker faz quatro trabalhos: **aceitar** publishes e retornar imediatamente; **casar** cada mensagem com as assinaturas (por nome de tópico, hierarquicamente — `orders.*` — ou por atributos de conteúdo); **entregar** uma cópia independente por assinante, com retry conforme o nível de garantia; e **reter** mensagens para assinantes offline onde a durabilidade estiver configurada — o desacoplamento no tempo que deixa um serviço fazer deploy ao meio-dia e recuperar o que perdeu. Uma nota de vocabulário que vale a frase: uma *mensagem* é o envelope; um *evento* — "isto aconteceu, no passado" — é o que o pub/sub normalmente carrega, e se ele carrega só o fato ou o estado completo é a distinção de [Fowler](https://martinfowler.com/articles/201701-event-driven.html) entre event notification e event-carried state transfer.

## Pub/sub vs. filas de mensagens vs. padrão observer

As duas confusões, resolvidas em uma tabela:

| | Pub/sub | Fila de mensagens | Observer |
| --- | --- | --- | --- |
| Entrega | Cada assinante recebe uma cópia | Exatamente um worker consome cada mensagem | O sujeito chama cada observador |
| Propósito | Transmitir eventos | Distribuir trabalho | Reagir a estado in-process |
| Acoplamento | Nenhum — mediado pelo broker | Nenhum — mediado pela fila | Referências diretas a objetos |
| Timing | Assíncrono | Assíncrono | Geralmente síncrono |
| Fronteira | Entre processos/sistemas | Entre workers | Dentro de um processo |
| Forma canônica | 1 evento → N reações | N jobs → M workers | 1 objeto → seus listeners |

A frase que sobrevive à reunião: **uma fila distribui o trabalho; pub/sub o duplica.** E observer não é um "pub/sub pequeno" — a indireção do broker é exatamente o que falta ao observer, e por isso refatorar um observer para pub/sub é uma mudança arquitetural, não uma renomeação. Na prática os brokers oferecem as duas formas: consumer groups transformam um tópico em fila por grupo (a jogada de assinatura do [Kafka](https://kafka.apache.org/documentation/#design)), exchanges de fanout transformam um sistema de filas em pub/sub.

## Garantias de entrega: at-most-once vs. at-least-once vs. exactly-once

| Garantia | Modo de falha | Custo | Seu handler deve | Escolha quando |
| --- | --- | --- | --- | --- |
| At-most-once | Mensagens podem sumir | O mais barato e rápido | Tolerar lacunas | Dados efêmeros: presença, cotações, métricas |
| At-least-once | Duplicatas chegam | Acks + retries | **Ser idempotente** | O padrão para eventos de negócio |
| Exactly-once | Restrito, complexo | Dedup + coordenação | Ainda ser idempotente | Caminhos estreitos onde o broker suporta |

Os níveis de QoS 0/1/2 do [MQTT](https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html) mapeiam exatamente para esses três — uma confirmação elegante de que a tricotomia é fundamental, não marketing de fornecedor. A verdade de engenharia: exactly-once de ponta a ponta é inatingível no caso geral (o problema dos Dois Generais usando crachá de broker); sistemas que o anunciam combinam entrega at-least-once com deduplicação. Por isso o contrato real do padrão está escrito no seu handler: **at-least-once + idempotência** — deduplique por ID de mensagem, use upserts com chave na entidade ou cheque a versão antes de aplicar — transforma duplicatas de bugs em no-ops.

## Ordenação, dead letters e design de tópicos

Três realidades operacionais que os diagramas introdutórios pulam. **Ordenação:** fan-out para consumidores paralelos não tem ordem global; brokers a restauram por partição ou chave de ordenação ao preço do paralelismo — desenhe handlers que apliquem eventos por ID e versão da entidade, não pela sequência de chegada, e o problema quase se dissolve. **Mensagens venenosas:** uma mensagem cujo processamento sempre lança erro vai tentar de novo para sempre sob at-least-once; limite as tentativas de entrega e roteie as falhas para uma **fila de dead-letter** para triagem, ou um evento ruim trava o tópico. **Design de tópicos:** nomeie hierarquicamente (`orders.paid`, `orders.refunded`, curinga `orders.*`), mantenha a granularidade no nível em que os assinantes de fato diferem e evolua os schemas de mensagem aditivamente — assinantes ignoram campos desconhecidos; quebras ganham um novo tópico versionado (`orders.v2`) com janela de migração, exatamente como uma versão de API.

## Casos de uso comuns

- **Integração de microsserviços** — serviços de times diferentes reagindo aos [eventos](/glossary/pt/arquitetura-desacoplada/) uns dos outros sem chamadas diretas nem agendas de deploy compartilhadas.
- **Recursos de tempo real no cliente** — fan-out de chat, dashboards ao vivo, [presença](/glossary/presence-online-status/): pub/sub sobre WebSockets na borda.
- **Telemetria de IoT** — milhares de dispositivos publicando via MQTT; consumidores de alertas a analytics assinando de forma independente.
- **Invalidação de cache e replicação** — uma escrita publicada, cada cache e réplica notificados.
- **Pipelines de processamento paralelo** — um evento disparando fulfillment, notificação e analytics ao mesmo tempo, cada um no próprio ritmo.

## Você deveria usar pub/sub? Matriz de decisão

| Pub/sub encaixa quando… | Prefira outra coisa quando… |
| --- | --- |
| Um evento interessa a vários consumidores independentes | Um único consumidor: uma fila, ou só uma chamada |
| Produtores e consumidores fazem deploy separadamente | Quem chama precisa da resposta agora → request-response |
| Consistência eventual é aceitável | Atomicidade entre as partes é exigida → transações/Saga |
| Assinantes entram e saem ao longo do tempo | Ordem global estrita é inegociável |
| Carga com picos precisa de buffer entre sistemas | O sistema inteiro cabe em um processo → observer |

## Limitações e trade-offs

- **O debug atravessa um broker.** "Quem consumiu isto e por que falhou?" exige IDs de correlação e tracing; o desacoplamento que liberta os times também esconde a causalidade.
- **Sem respostas, por design.** Fluxos que precisam de resposta têm de modelá-la como novas mensagens — latência extra e máquinas de estado onde antes bastava uma chamada de função.
- **O broker é infraestrutura.** Disponibilidade, capacidade, segurança e políticas de retenção da camada de mensageria viram trabalho de plataforma; um broker fora do ar é um multiplicador de outages.
- **A cegueira do publicador corta dos dois lados.** Publicadores não observam a saúde dos assinantes; um consumidor falhando em silêncio perde dados, a menos que exista monitoramento de dead-letter.
- **Garantias custam throughput.** Chaves de ordenação serializam, exactly-once coordena, durabilidade persiste — cada reforço de semântica gasta performance; compre só o que os dados precisam.

## Pub/Sub no Back4app

O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. O padrão aparece aqui na borda do cliente: as [Live Queries](/glossary/pt/live-queries-tempo-real/) são pub/sub em que a *query é o tópico* — assinantes registram um predicado, qualquer escrita que casar é publicada para cada assinante por uma frota gerenciada de [WebSockets](/glossary/pt/websockets/), com permissões checadas por assinante e fan-out por conta da plataforma, como nas abas de código acima. Reações server-side se compõem do mesmo jeito: triggers de Cloud Code assinam mudanças de dados (`afterSave` como assinatura de tópico em espírito), e funções agendadas drenam trabalho publicado como linhas. Para streaming pesado entre serviços você ainda buscaria um broker dedicado como Kafka ou RabbitMQ — mas, para os casos comuns de produto, o transmitir-ao-mudar já vem com o backend.
