A maior parte das integrações que vemos quebrar não quebra por bug. Quebra porque foi feita acoplando lógica de negócio a contrato de fornecedor — e o fornecedor mudou.
Camadas que valem a pena
Toda integração robusta tem três camadas claras:
// 1. Adapter — fala o dialeto do fornecedor
class StripeAdapter {
async createPayment(input: StripeInput): Promise<StripeResponse> { /*…*/ }
}
// 2. Domain Service — fala a linguagem do seu negócio
class PaymentService {
async charge(order: Order): Promise<PaymentResult> {
const stripeInput = this.toStripeInput(order);
const response = await this.stripe.createPayment(stripeInput);
return this.fromStripeResponse(response);
}
}
// 3. Use case — orquestra
class CheckoutUseCase {
async execute(cart: Cart) {
const order = await this.orders.create(cart);
const payment = await this.payments.charge(order);
await this.notifications.confirm(order, payment);
}
}
Trocar Stripe por outro gateway? Reescreve o adapter. Lógica de negócio fica intacta.
Eventos > polling, quase sempre
Webhooks com fila e retry estruturados são quase sempre superiores a polling agendado. Custam mais para configurar pela primeira vez, mas escalam linearmente.
A regra prática: se você está fazendo polling a cada 5 minutos ou mais frequente, considere webhooks. Se está fazendo polling a cada hora ou mais raro, polling está OK.
Observabilidade desde o dia 1
Toda integração precisa, no mínimo:
- Log estruturado de cada chamada (input, output, latência)
- Métrica de taxa de sucesso/erro por endpoint
- Alerta automático quando a taxa de erro passa de um limiar
Sem isso, você vai descobrir que a integração quebrou quando o cliente reclamar.
Em produção, isso vira o quê?
Em projetos da etcweb., isso normalmente toma a forma de:
- Node.js + TypeScript para o domain
- OpenAPI para documentar contratos internos
- Redis para filas leves, RabbitMQ quando o volume justifica
- Sentry + Logflare (ou equivalentes) para observabilidade
Nada exótico — só rigor.