Pular para o conteúdo
Automação

Integração de Sistemas: APIs REST, Webhooks e GraphQL em Ação

Admin5 min de leitura
Integração de Sistemas: APIs REST, Webhooks e GraphQL em Ação

Integração de Sistemas: APIs REST, Webhooks e GraphQL em Ação

Objetivo – Mostrar, com código funcional, como projetar e implementar integrações entre sistemas usando três abordagens complementares: APIs REST, Webhooks e GraphQL. O artigo inclui boas práticas de versionamento, segurança, tratamento de erros e orquestração via API Gateway.

Tecnologia e Inovação

📌 Introdução

Em ambientes corporativos modernos, a troca de informações entre aplicações raramente acontece de forma isolada. Seja um ERP que precisa notificar um CRM, um serviço de pagamento que avisa um marketplace ou um front‑end que consome dados de múltiplas fontes, a integração via API tornou‑se a espinha dorsal da arquitetura de negócios.

Existem três padrões que, combinados, cobrem a maioria dos casos de uso:

PadrãoQuando usarPrincipais vantagens
RESTOperações CRUD, recursos bem definidos, alta interoperabilidadeSimplicidade, cache HTTP, amplo suporte
WebhooksNotificações assíncronas, eventos em tempo real, redução de pollingLatência baixa, menor carga no provedor
GraphQLConsultas flexíveis, múltiplas fontes de dados, front‑ends ricosEvita over/under‑fetch, versionamento implícito

Neste post vamos criar exemplos reais que podem ser copiados para projetos de qualquer porte. O foco será em Node.js (para REST), Python (para Webhooks) e Apollo Server (para GraphQL), mas os princípios são transferíveis para outras linguagens.


1️⃣ Construindo uma API REST robusta

1.1. Principais decisões de design

  • Versionamento na URL/api/v1/customers
  • Formato de payload – JSON UTF‑8
  • Autenticação – OAuth 2.0 Bearer Token
  • Tratamento de erros – padrão RFC 7807 (Problem Details)
  • 1.2. Implementação em Node.js (Express)

    // src/server.js
    

    const express = require('express'); const helmet = require('helmet'); const morgan = require('morgan'); const { expressjwt: jwt } = require('express-jwt'); const jwksRsa = require('jwks-rsa');

    const app = express();

    // Middlewares essenciais app.use(helmet()); app.use(express.json()); app.use(morgan('combined'));

    // Configuração OAuth2 (Auth0 como exemplo) const checkJwt = jwt({ secret: jwksRsa.expressJwtSecret({ cache: true, rateLimit: true, jwksUri: 'https://YOUR_DOMAIN/.well-known/jwks.json' }), audience: 'https://api.seusistema.com', issuer: 'https://YOUR_DOMAIN/', algorithms: ['RS256'] });

    // Rotas versionadas const router = express.Router();

    router.get('/customers', async (req, res, next) => { try { // Simulação de busca no banco const customers = await db.query('SELECT FROM customers LIMIT 100'); res.json(customers); } catch (err) { next(err); } });

    router.post('/customers', async (req, res, next) => { try { const { name, email } = req.body; const result = await db.query( 'INSERT INTO customers (name, email) VALUES ($1, $2) RETURNING ', [name, email] ); res.status(201).json(result.rows[0]); } catch (err) { next(err); } });

    // Aplicando autenticação apenas nas rotas que exigem app.use('/api/v1', checkJwt, router);

    // Middleware de erro padronizado app.use((err, _req, res, _next) => { const status = err.status || 500; res.status(status).json({ type: 'https://example.com/problem', title: err.message, status, detail: err.stack }); });

    const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(API rodando na porta ${PORT}));

    Destaques do código

    helmet protege contra vulnerabilidades de cabeçalhos HTTP. express-jwt + jwks-rsa valida tokens assinados por um provedor OAuth2, evitando a necessidade de armazenar chaves secretas. Middleware de erro devolve um objeto conforme RFC 7807, facilitando o consumo por clientes automatizados.

    1.3. Testando a API com curl

    # Listar clientes (token fictício)
    

    curl -H "Authorization: Bearer <ACCESS_TOKEN>" \ https://api.seusistema.com/api/v1/customers

    Criar cliente

    curl -X POST -H "Content-Type: application/json" \ -H "Authorization: Bearer <ACCESS_TOKEN>" \ -d '{"name":"Ana Silva","email":"ana@example.com"}' \ https://api.seusistema.com/api/v1/customers


    2️⃣ Webhooks: comunicação orientada a eventos

    2.1. Por que usar Webhooks?

    Push imediato – O provedor envia o evento assim que ele ocorre. Redução de chamadas – Elimina o polling constante, economizando banda e recursos. Desacoplamento – O receptor pode processar o evento de forma assíncrona.

    2.2. Segurança dos Webhooks

    EstratégiaImplementação
    Assinatura HMACO provedor inclui um cabeçalho X-Signature calculado com um segredo compartilhado.
    IP WhitelistingPermitir apenas requisições de faixas IP conhecidas.
    TLSExigir HTTPS para evitar intercepção.

    2.3. Receptor em Python (Flask)

    # webhook_receiver.py
    

    import hmac import hashlib import json from flask import Flask, request, abort

    app = Flask(__name__)

    Segredo compartilhado entre os sistemas

    WEBHOOK_SECRET = b'seu_segredo_super_secreto'

    def verify_signature(payload, signature): expected = hmac.new(WEBHOOK_SECRET, payload, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, signature)

    @app.route('/webhook/orders', methods=['POST']) def orders_webhook(): signature = request.headers.get('X-Signature') if not signature or not verify_signature(request.data, signature): abort(401, description='Assinatura inválida')

    event = request.get_json() # Processamento assíncrono (ex.: enfileirar no RabbitMQ) print(f"Evento recebido: {event['type']} - ID {event['data']['order_id']}") return '', 204

    if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=False)

    2.4. Emissor de Webhook (Node.js)

    // sender.js
    

    const axios = require('axios'); const crypto = require('crypto');

    const WEBHOOK_URL = 'https://meuservico.com/webhook/orders'; const SECRET = 'seu_segredo_super_secreto';

    function signPayload(payload) { return crypto .createHmac('sha256', SECRET) .update(JSON.stringify(payload)) .digest('hex'); }

    async function sendOrderCreated(order) { const payload = { type: 'order.created', data: order };

    const signature = signPayload(payload);

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

    // Exemplo de uso sendOrderCreated({ order_id: 12345, amount: 250.0 }) .then(() => console.log('Webhook enviado')) .catch(err => console.error('Falha ao enviar webhook:', err));

    Dica: Use filas (RabbitMQ, SQS) no receptor para garantir resiliência caso o processamento demore ou falhe.


    3️⃣ GraphQL: consultas flexíveis em um único endpoint

    3.1. Quando GraphQL faz sentido?

    Front‑ends móveis que precisam de apenas alguns campos de um recurso grande. Dashboard unificado que combina dados de múltiplas APIs.

    • Evolução de schema sem versionamento explícito.

    3.2. Schema básico com Apollo Server

    ``js // graphql-server.js const { ApolloServer, gql } = require('apollo-server'); const fetch = require('node-fetch');

    // Definição do schema const typeDefs = gql type Customer { id: ID! name: String! email: String! orders: [Order!]! }

    type Order { id: ID! total: Float! createdAt: String! }

    type Query { customers: [Customer!]! customer(id: ID!): Customer } ;

    // Resolvers que consomem duas APIs distintas (REST + outro serviço) const resolvers = { Query: { customers: async () => { const resp = await fetch('https://api.seusistema.com/api/v1/customers'); return resp.json(); }, customer: async (_, { id }) => { const resp = await fetch(https://api.seusistema.com/api/v1/custom

    Artigos relacionados