---
title: "Server-Sent Events (SSE): Reatividade Simples e Eficiente no Frontend"
slug: server-sent-events-microfrontends
date: 2025-06-21
category: "Microfrontends"
tags: ["server-sent-events", "sse", "microfrontends", "real-time", "reactivity", "event-source", "websocket-alternative"]
readTime: "7 min"
excerpt: "Como usar Server-Sent Events em microfrontends para fluxos de dados unidirecionais, notificações em tempo real, feature flags dinâmicas e comunicação entre Shell e MFEs."
url: https://eliseu.dev/blog/server-sent-events-microfrontends
---

O **Server-Sent Events (SSE)** continua sendo uma opção sólida para fluxos de dados unidirecionais no frontend — especialmente em contextos modernos de **Micro Frontends (MFEs)**, onde simplicidade, performance e escalabilidade são essenciais.

Hoje, o SSE vem sendo utilizado em combinações como:

- **Shells orquestradores** (Single-SPA, Module Federation, Zephyr)
- **Feature Flags dinâmicas** baseadas em AI
- **Edge Functions** (Cloudflare Workers, Vercel Functions)
- **Streams de eventos** (Redis Streams, Kafka, RabbitMQ)

## ✅ Vantagens do SSE no Cenário Atual

### **Simplicidade e Compatibilidade**
- ✅ **Baseado em HTTP** — sem handshakes adicionais
- ✅ **Compatível com infraestruturas modernas** (HTTP/2, CDN, Serverless)
- ✅ **Código leve**, sem dependências externas
- ✅ **Reconexão automática nativa** (EventSource)

### **Performance e Escalabilidade**
- ✅ **Ideal para notificações**, logs, atualizações contextuais
- ✅ **Baixo overhead** de conexão
- ✅ **Suporte nativo** a HTTP/2 multiplexing
- ✅ **Cache-friendly** com CDNs

## 🏗️ Aplicações em Arquiteturas de Micro Frontends

Em estruturas com **MFEs desacoplados**, o SSE pode ser mantido no Shell e os eventos propagados aos MFEs por meio de **CustomEvent**, mantendo o isolamento dos times e a reatividade em tempo real.

### **Exemplo com Single-SPA:**

```javascript
// Shell (root-app)
const source = new EventSource('/api/sse');
source.onmessage = ({ data }) => {
  const event = JSON.parse(data);
  window.dispatchEvent(new CustomEvent('sse:event', { detail: event }));
};

// MFE (qualquer framework)
useEffect(() => {
  const handler = (e) => handleIncomingData(e.detail);
  window.addEventListener('sse:event', handler);
  return () => window.removeEventListener('sse:event', handler);
}, []);
```

## 🎯 Exemplos de Uso Práticos

### **1. Atualização em Tempo Real de Feature Flags**
```javascript
// Shell - Feature Flags dinâmicas
const featureFlagsSource = new EventSource('/api/feature-flags/sse');

featureFlagsSource.onmessage = ({ data }) => {
  const flags = JSON.parse(data);
  
  // Broadcast para todos os MFEs
  window.dispatchEvent(new CustomEvent('feature-flags:update', {
    detail: flags
  }));
};

// MFE - Consumir feature flags
useEffect(() => {
  const handleFeatureFlags = (event) => {
    const flags = event.detail;
    setFeatureFlags(flags);
    
    // Renderização condicional baseada em flags
    if (flags.newCheckoutFlow) {
      renderNewCheckout();
    }
  };
  
  window.addEventListener('feature-flags:update', handleFeatureFlags);
  return () => window.removeEventListener('feature-flags:update', handleFeatureFlags);
}, []);
```

### **2. Notificações de Deploy para Atualização de MFEs**
```javascript
// Shell - Monitoramento de deploys
const deploySource = new EventSource('/api/deployments/sse');

deploySource.onmessage = ({ data }) => {
  const deployment = JSON.parse(data);
  
  if (deployment.status === 'completed') {
    // Notificar MFEs sobre nova versão disponível
    window.dispatchEvent(new CustomEvent('deployment:completed', {
      detail: {
        mfe: deployment.mfe,
        version: deployment.version,
        timestamp: deployment.timestamp
      }
    }));
  }
};

// MFE - Atualização automática
useEffect(() => {
  const handleDeployment = (event) => {
    const { mfe, version } = event.detail;
    
    if (mfe === 'current-mfe') {
      // Mostrar notificação de atualização
      showUpdateNotification(version);
    }
  };
  
  window.addEventListener('deployment:completed', handleDeployment);
  return () => window.removeEventListener('deployment:completed', handleDeployment);
}, []);
```

### **3. Log de Ações em Sistemas Multitenant**
```javascript
// Shell - Logs de auditoria
const auditSource = new EventSource('/api/audit/sse');

auditSource.onmessage = ({ data }) => {
  const auditLog = JSON.parse(data);
  
  // Filtrar por tenant atual
  if (auditLog.tenantId === getCurrentTenant()) {
    window.dispatchEvent(new CustomEvent('audit:log', {
      detail: auditLog
    }));
  }
};

// MFE - Exibir logs em tempo real
useEffect(() => {
  const handleAuditLog = (event) => {
    const log = event.detail;
    
    // Adicionar ao feed de atividades
    addToActivityFeed({
      user: log.user,
      action: log.action,
      timestamp: log.timestamp,
      details: log.details
    });
  };
  
  window.addEventListener('audit:log', handleAuditLog);
  return () => window.removeEventListener('audit:log', handleAuditLog);
}, []);
```

### **4. Monitoramento de Estados por Usuário**
```javascript
// Shell - Estados de sessão
const sessionSource = new EventSource('/api/session/sse');

sessionSource.onmessage = ({ data }) => {
  const sessionUpdate = JSON.parse(data);
  
  // Atualizar estado global da sessão
  window.dispatchEvent(new CustomEvent('session:update', {
    detail: sessionUpdate
  }));
};

// MFE - Sincronização de estado
useEffect(() => {
  const handleSessionUpdate = (event) => {
    const session = event.detail;
    
    // Sincronizar estado local com servidor
    setUserStatus(session.status);
    setLastActivity(session.lastActivity);
    
    // Renderização condicional baseada em permissão
    if (session.permissions.includes('admin')) {
      showAdminPanel();
    }
  };
  
  window.addEventListener('session:update', handleSessionUpdate);
  return () => window.removeEventListener('session:update', handleSessionUpdate);
}, []);
```

## 📊 Comparativo Técnico (Cenário 2025)

| Tecnologia | Indicado para | Considerações |
|------------|---------------|----------------|
| **SSE** | Stream unidirecional leve e confiável | Sem suporte a binários |
| **WebSocket** | Bidirecional em tempo real | Requer mais infraestrutura e estado |
| **WebTransport** | Baixa latência sobre HTTP/3 | Suporte ainda limitado nos browsers |
| **Polling** | Simplicidade extrema | Ineficiente e pouco reativo |

## 🔧 Implementação Avançada

### **Classe SSE Manager**

```javascript
class SSEManager {
  constructor(baseUrl) {
    this.baseUrl = baseUrl;
    this.connections = new Map();
    this.eventHandlers = new Map();
  }
  
  connect(endpoint, options = {}) {
    const url = `${this.baseUrl}${endpoint}`;
    const source = new EventSource(url);
    
    source.onopen = () => {
      console.log(`🔗 SSE conectado: ${endpoint}`);
    };
    
    source.onmessage = ({ data }) => {
      try {
        const event = JSON.parse(data);
        this.broadcastEvent(endpoint, event);
      } catch (error) {
        console.error('Erro ao processar evento SSE:', error);
      }
    };
    
    source.onerror = (error) => {
      console.error(`❌ Erro SSE em ${endpoint}:`, error);
    };
    
    this.connections.set(endpoint, source);
    return source;
  }
  
  broadcastEvent(endpoint, data) {
    const eventName = `sse:${endpoint.replace('/', ':')}`;
    window.dispatchEvent(new CustomEvent(eventName, { detail: data }));
  }
  
  disconnect(endpoint) {
    const source = this.connections.get(endpoint);
    if (source) {
      source.close();
      this.connections.delete(endpoint);
    }
  }
  
  disconnectAll() {
    this.connections.forEach((source, endpoint) => {
      source.close();
    });
    this.connections.clear();
  }
}

// Uso global
window.sseManager = new SSEManager('/api');
```

### **Hook React Personalizado**

```javascript
import { useEffect, useState } from 'react';

export function useSSE(endpoint, options = {}) {
  const [data, setData] = useState(null);
  const [isConnected, setIsConnected] = useState(false);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    if (!window.sseManager) {
      setError('SSE Manager não inicializado');
      return;
    }
    
    const eventName = `sse:${endpoint.replace('/', ':')}`;
    
    const handleEvent = (event) => {
      setData(event.detail);
      setIsConnected(true);
      setError(null);
    };
    
    const handleError = () => {
      setIsConnected(false);
      setError('Erro na conexão SSE');
    };
    
    // Conectar ao endpoint
    const source = window.sseManager.connect(endpoint);
    
    // Configurar listeners
    window.addEventListener(eventName, handleEvent);
    source.addEventListener('error', handleError);
    
    return () => {
      window.removeEventListener(eventName, handleEvent);
      source.removeEventListener('error', handleError);
      window.sseManager.disconnect(endpoint);
    };
  }, [endpoint]);
  
  return { data, isConnected, error };
}
```

## 🔍 Integração com Observabilidade

### **Logging com Last-Event-ID**

```javascript
// Suporte a reconexão com Last-Event-ID
const source = new EventSource('/api/sse', {
  withCredentials: true
});

let lastEventId = null;

source.onmessage = ({ data, lastEventId: eventId }) => {
  lastEventId = eventId;
  
  // Log para observabilidade
  console.log('SSE Event:', {
    data: JSON.parse(data),
    eventId,
    timestamp: new Date().toISOString()
  });
};

// Reconexão com Last-Event-ID
source.addEventListener('error', () => {
  setTimeout(() => {
    const newSource = new EventSource(`/api/sse?lastEventId=${lastEventId}`);
    // ... reconectar
  }, 5000);
});
```

### **Monitoramento com Datadog/New Relic**

```javascript
// Métricas customizadas
function trackSSEMetrics(endpoint, eventType, latency) {
  // Datadog
  if (window.DD_RUM) {
    window.DD_RUM.addAction('sse_event', {
      endpoint,
      eventType,
      latency
    });
  }
  
  // New Relic
  if (window.newrelic) {
    window.newrelic.addPageAction('sse_event', {
      endpoint,
      eventType,
      latency
    });
  }
}
```

## 🚀 Benefícios em Produção

### **Para Microfrontends**
- ✅ **Comunicação desacoplada** entre Shell e MFEs
- ✅ **Reatividade em tempo real** sem complexidade
- ✅ **Isolamento de responsabilidades** mantido
- ✅ **Escalabilidade horizontal** facilitada

### **Para Infraestrutura**
- ✅ **Baixo custo operacional** comparado ao WebSocket
- ✅ **Compatibilidade com CDNs** e edge computing
- ✅ **Suporte nativo** a HTTP/2
- ✅ **Facilita auditoria** e rastreabilidade

### **Para Desenvolvedores**
- ✅ **Implementação simples** sem dependências
- ✅ **Debugging facilitado** com logs nativos
- ✅ **Fallback automático** para reconexão
- ✅ **Integração fácil** com observabilidade

## 📚 Referências e Materiais Recomendados

- **MDN Web Docs** – [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)
- **WHATWG** – [EventSource Spec](https://html.spec.whatwg.org/multipage/server-sent-events.html)
- **Cloudflare Workers** – [SSE Implementation](https://developers.cloudflare.com/workers/examples/server-sent-events/)
- **GitHub** – [SSE bridge com Kafka](https://github.com/example/sse-kafka-bridge)

## 🎯 Conclusão

O uso de **SSE em 2025** se mostra coerente com a busca por arquiteturas desacopladas, reativas e de baixo custo operacional. Quando a comunicação bidirecional não é necessária, o SSE é uma solução leve, resiliente e facilmente auditável — especialmente em ambientes com múltiplos MFEs e shell centralizado.

### **Quando Usar SSE:**
- ✅ **Notificações** em tempo real
- ✅ **Feature flags** dinâmicas
- ✅ **Logs de auditoria** em tempo real
- ✅ **Atualizações de estado** unidirecionais
- ✅ **Monitoramento** de sistemas

### **Quando Evitar SSE:**
- ❌ **Comunicação bidirecional** necessária
- ❌ **Dados binários** para transmitir
- ❌ **Latência ultra-baixa** crítica
- ❌ **Browsers muito antigos** sem suporte

*Este artigo apresenta uma solução prática para reatividade em tempo real em arquiteturas de microfrontends. Para discussões técnicas, implementações ou dúvidas sobre SSE e comunicação entre MFEs, me encontre no [LinkedIn](https://linkedin.com/in/eliseusantos) ou [GitHub](https://github.com/EliseuSantos).*