Pular para o conteúdo
Integrações

Conectando Sistemas com APIs REST e Webhooks: Guia Prático

Admin6 min de leitura
Conectando Sistemas com APIs REST e Webhooks: Guia Prático

Conectando Sistemas com APIs REST e Webhooks: Guia Prático

Tecnologia e Inovação

Introdução

Em um cenário onde aplicações precisam trocar dados de forma rápida, segura e escalável, APIs e webhooks tornaram‑se os pilares das integrações modernas. Enquanto as APIs REST permitem que um cliente solicite recursos sob demanda, os webhooks entregam eventos de forma assíncrona, reduzindo a necessidade de polling constante.

Este artigo apresenta, de forma prática, como planejar, implementar e manter integrações entre sistemas usando:

APIs REST (HTTP/JSON); Webhooks para eventos em tempo real; Estratégias de autenticação e controle de tráfego; Documentação automática com OpenAPI/Swagger.

Ao final, você terá código funcional em Python (Flask) e Node.js (Express) que pode ser copiado e adaptado ao seu projeto.


1. Conceitos Fundamentais de APIs e Webhooks

CaracterísticaAPI RESTWebhook
IniciaçãoCliente solicita (pull)Servidor envia (push)
FormatoHTTP + JSON (ou XML)HTTP POST com payload JSON
Uso típicoCRUD de recursos, consultasNotificações de eventos (ex.: pagamento concluído)
EscalabilidadeDepende de taxa de requisiçõesDepende de volume de eventos gerados
SegurançaAutenticação por token, OAuth2, API keysValidação de assinatura, secret token

1.1 Quando usar cada abordagem?

  • API REST – Ideal para operações onde o consumidor decide quando e o que precisa. Ex.: buscar lista de clientes, atualizar um pedido.
  • Webhook – Indicado quando o produtor de dados precisa avisar o consumidor imediatamente, sem que este faça polling. Ex.: disparar um e‑mail ao confirmar pagamento.
  • 1.2 Principais padrões de comunicação

    JSON – Formato de dados leve e amplamente suportado. HTTPS – Obrigatório para proteger a confidencialidade e integridade dos dados. Status codes – Use códigos HTTP corretos (200, 201, 400, 401, 429, 500) para facilitar o tratamento de erros.


    2. Estratégias de Autenticação e Controle de Tráfego

    2.1 OAuth2 – O padrão de fato

    OAuth2 permite que um cliente obtenha um access token que será enviado em cada requisição via cabeçalho Authorization: Bearer . O fluxo Client Credentials é o mais simples para integrações máquina‑a‑máquina.

    Exemplo de request de token (cURL)

    curl -X POST https://auth.example.com/oauth/token \
    

    -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials&client_id=MY_CLIENT_ID&client_secret=MY_CLIENT_SECRET"

    Resposta:

    {
    

    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...", "token_type": "Bearer", "expires_in": 3600 }

    2.2 API Keys e HMAC

    Para webhooks, a prática mais comum é enviar um secret compartilhado que o receptor usa para gerar um HMAC SHA‑256 da carga e comparar com o cabeçalho X-Signature. Isso garante que a chamada realmente veio da origem esperada.

    Exemplo de validação em Node.js (Express)

    const crypto = require('crypto');
    

    function verifySignature(req, res, next) { const signature = req.headers['x-signature']; const payload = JSON.stringify(req.body); const secret = process.env.WEBHOOK_SECRET;

    const hash = crypto.createHmac('sha256', secret).update(payload).digest('hex'); if (hash !== signature) { return res.status(401).send('Invalid signature'); } next(); }

    2.3 Rate Limiting

    Para evitar sobrecarga, implemente rate limiting por IP ou por token. Bibliotecas como express-rate-limit (Node.js) ou Flask-Limiter (Python) facilitam a configuração.

    Exemplo rápido em Flask

    from flask import Flask, request, jsonify
    

    from flask_limiter import Limiter from flask_limiter.util import get_remote_address

    app = Flask(__name__) limiter = Limiter(app, key_func=get_remote_address)

    @app.route('/clientes', methods=['GET']) @limiter.limit("100 per minute") def listar_clientes(): # lógica de listagem return jsonify([...])


    3. Padronização e Documentação com OpenAPI

    A OpenAPI Specification (OAS) permite descrever toda a API em um único documento YAML/JSON. Ferramentas como Swagger UI ou Redoc geram documentação interativa automaticamente.

    3.1 Estrutura mínima de um spec

    openapi: 3.0.3
    

    info: title: API de Pedidos version: 1.0.0 servers: - url: https://api.example.com/v1 paths: /pedidos: get: summary: Lista todos os pedidos security: - bearerAuth: [] responses: '200': description: Lista de pedidos content: application/json: schema: type: array items: $ref: '#/components/schemas/Pedido' components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT schemas: Pedido: type: object properties: id: type: integer status: type: string total: type: number format: float

    3.2 Gerando código a partir do spec

    Ferramentas como openapi-generator criam stubs em diversas linguagens. Por exemplo:

    openapi-generator-cli generate -i api.yaml -g python-flask -o ./generated-flask

    Isso gera um esqueleto de API Flask já com rotas, validação de entrada e documentação Swagger integrada.


    Exemplos Práticos

    3.1 API REST em Python (Flask)

    # app.py
    

    from flask import Flask, request, jsonify, abort from flask_limiter import Limiter from flask_limiter.util import get_remote_address import requests import os

    app = Flask(__name__) limiter = Limiter(app, key_func=get_remote_address)

    API_KEY = os.getenv('API_KEY') WEBHOOK_URL = os.getenv('WEBHOOK_URL')

    def authorize(): token = request.headers.get('Authorization') if not token or token != f'Bearer {API_KEY}': abort(401, description='Invalid token')

    @app.route('/clientes', methods=['GET']) @limiter.limit('60/minute') def listar_clientes(): authorize() # Simulação de dados clientes = [ {"id": 1, "nome": "Ana", "email": "ana@example.com"}, {"id": 2, "nome": "Bruno", "email": "bruno@example.com"}, ] return jsonify(clientes)

    @app.route('/clientes', methods=['POST']) @limiter.limit('30/minute') def criar_cliente(): authorize() data = request.get_json() if not data.get('nome') or not data.get('email'): abort(400, description='Nome e e‑mail são obrigatórios') # Persistir no banco (omisso) novo = {"id": 3, data} # Dispara webhook de criação payload = {"event": "cliente.criado", "data": novo} headers = { "Content-Type": "application/json", "X-Signature": generate_hmac(payload) } requests.post(WEBHOOK_URL, json=payload, headers=headers) return jsonify(novo), 201

    def generate_hmac(payload): import hmac, hashlib, json secret = os.getenv('WEBHOOK_SECRET').encode() message = json.dumps(payload).encode() return hmac.new(secret, message, hashlib.sha256).hexdigest()

    if __name__ == '__main__': app.run(debug=True)

    Pontos chave do exemplo

    Rate limiting com flask_limiter. Autenticação simples via token no cabeçalho. Webhook disparado após criação de cliente, usando HMAC para assinatura.

    3.2 API REST em Node.js (Express)

    ``js // server.js require('dotenv').config(); const express = require('express'); const rateLimit = require('express-rate-limit'); const axios = require('axios'); const crypto = require('crypto');

    const app = express(); app.use(express.json());

    const limiter = rateLimit({ windowMs: 60 * 1000, max: 80, // 80 req/min por IP }); app.use(limiter);

    const API_KEY = process.env.API_KEY; const WEBHOOK_URL = process.env.WEBHOOK_URL; const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

    function verifyAuth(req, res, next) { const auth = req.headers.authorization; if (!auth || auth !== Bearer ${API_KEY}`) { return res.status(401).json({ error: 'Invalid token' }); } next(); }

    app.get('/produtos', verifyAuth, (req, res) => { const produtos = [ { id: 10, nome: 'Camiseta', preco: 49.9 }, { id: 11, nome: 'Caneca', preco: 29.9 }, ]; res.json(produtos); });

    app.post('/pedidos', verifyAuth, async (req, res) => { const { clienteId, itens } = req.body; if (!clienteId || !Array.isArray(itens) || itens.length === 0) { return res.status(400).json({ error: 'Payload inválido' }); }

    const pedido = { id: 1001, clienteId, itens, status: 'criado' };

    // Envia webhook de novo pedido const payload = { event: 'pedido.criado', data: pedido }; const signature = crypto .createHmac('sha256', WEBHOOK_SECRET) .update(JSON.stringify(payload)) .digest('hex');

    try { await axios.post(WEBHOOK_URL, payload, { headers: { 'X-Signature': signature, 'Content-Type': 'application/json' }, }); } catch (

    Artigos relacionados