heimdall-api-platform
v1.22.0
Published
**Um microgateway de alta performance para APIs, com orquestração inteligente e roteamento dinâmico.**
Maintainers
Readme
Heimdall API Platform
Um microgateway de alta performance para APIs, com orquestração inteligente e roteamento dinâmico.
🚀 O que é o Heimdall API Platform?
O Heimdall API Platform é um microgateway projetado para lidar com orquestração de APIs, roteamento dinâmico e integração entre microsserviços de forma flexível e performática.
Ideal para arquiteturas modernas, legadas ou híbridas, ele permite centralizar e controlar fluxos de requisições com segurança, cache, validação de licença e observabilidade.
✅ Problemas que ele resolve
- Roteamento inteligente entre múltiplas APIs
- Orquestração de serviços e fluxos condicionais
- Aplicação de padrões de segurança e autenticação
- Cache de respostas via Redis
- Observabilidade com OpenSearch
- Proteção contra ataques DDoS e throttling de requisições
- Transformações dinâmicas de dados de request em tempo de execução
- Facilidade de integração com ambientes heterogêneos (legado + novo)
- Padronização de erros e tratamento uniforme
- Geração de correlation id para rastreamento de requisições
🧩 Funcionalidades Principais
- ✅ Gateway de APIs leve e flexível
- 🔁 Roteamento dinâmico baseado em configurações
- ⚙️ Orquestração de múltiplos fluxos por rota
- 🔗 Agregação de vários serviços em uma única requisição utilizando fluxos
- 🔐 Validação de licença (produção exige chave válida)
- 📦 Cache com Redis (opcional, mas recomendado)
- 🔍 Observabilidade com OpenSearch
- 📊 Métricas Prometheus (
/metrics/prometheus) e health checks reais (/health/live,/health/ready) - 🪪 Correlation ID + distributed trace context (W3C
traceparent, Datadog, B3) propagados viaAsyncLocalStorage - 📄 Documentação automática com Swagger e Redocly
- 🎭 Suporte a mocks estáticos e dinâmicos
- ▶️ Execução de functions customizadas, integração com clientes de API e mocks internos
- 🛠️ Padronização de erros e respostas de falha
- 🔖 Geração automática de correlation id para rastreamento
- ☁️ Totalmente compatível com AWS Lambda e Google Cloud Functions
📦 Pré-requisitos
- Node.js v18 ou superior
📥 Instalação via NPM
npm install heimdall-api-platform🔧 Exemplos de Configuração de Rotas
1. execute-function
module.exports = {
name: 'executeFunction',
description: 'Execute Function',
method: 'POST',
route: '/execute_function',
indexedResult: false,
responseHeaders: {
'Content-Type': 'application/json;charset=UTF-8'
},
flow: [
{
resultVariable: '.',
skipErrors: false,
cacheEnable: true,
cacheTtl: 10, // TTL em segundos
operation: {
functionName: 'return-body-result',
type: 'function'
}
}
]
};| Atributo | Descrição |
| ----------------- | ----------------------------------------------- |
| name | Identificador único da rota/configuração. |
| description | Descrição para documentação. |
| method | Método HTTP (GET, POST, etc.). |
| route | Caminho exposto no gateway. |
| indexedResult | Se deve indexar o resultado para uso posterior. |
| responseHeaders | Headers fixos retornados na resposta. |
Detalhes do flow
| Campo | Descrição |
| ---------------- | -------------------------------------------- |
| resultVariable | Variável onde armazenar o saída da operação. |
| skipErrors | Se true, ignora erros e continua o fluxo. |
| cacheEnable | Se true, ativa cache para esta operação. |
| cacheTtl | Tempo de vida (segundos) do cache. |
| operation | Configuração da operação (function). |
Configuração operation
| Campo | Descrição |
| -------------- | --------------------------------------- |
| functionName | Nome da função registrada no framework. |
| type | Tipo de operação (function). |
2. execute-mock
module.exports = {
name: 'executeMock',
description: 'Execute Mock',
method: 'GET',
route: '/execute_mock',
indexedResult: false,
responseHeaders: {
'Content-Type': 'application/json;charset=UTF-8'
},
flow: [
{
resultVariable: '.',
skipErrors: false,
operation: {
file: 'demo-mock.json',
type: 'mock'
}
}
]
};| Atributo | Descrição |
| ----------------- | ------------------------------------ |
| name | Identificador único da rota de mock. |
| description | Descrição para documentação. |
| method | Método HTTP. |
| route | Caminho exposto no mock. |
| indexedResult | Se deve indexar o mock. |
| responseHeaders | Headers fixos para resposta do mock. |
Detalhes do flow
| Campo | Descrição |
| ---------------- | ----------------------------------------- |
| resultVariable | Variável que receberá o conteúdo do mock. |
| skipErrors | Se true, ignora erros. |
| operation | Configuração da operação (mock). |
Configuração operation
| Campo | Descrição |
| --------- | ---------------------------------- |
| file | Caminho para arquivo JSON de mock. |
| type | Tipo de operação (mock). |
3. execute-api-rest (usando client)
module.exports = {
name: 'addressByZipcodeService',
description: 'Get Address By Zipcode',
method: 'GET',
route: '/:zipcode/by_client_api',
indexedResult: false,
responseHeaders: {
'Content-Type': 'application/json;charset=UTF-8'
},
flow: [
{
resultVariable: '.',
skipErrors: false,
cacheEnable: false,
cacheTtl: 24 * 60 * 60 * 30, // 30 dias em segundos
cacheKey: '{{params.zipcode}}',
operation: {
clientName: 'viaCEP',
mergedHeaders: false,
headersTransformation: 'transformation-header-get-cep',
requestTransformation: 'transformation-request-get-cep',
responseTransformation: 'transformation-response-get-cep',
onError: 'on-error-get-cep',
onSuccess: 'on-success-get-cep',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'X-HEADER-CEP': '{{params.zipcode}}'
},
type: 'http',
method: 'GET',
path: '/{{params.zipcode}}/json'
}
}
]
};| Atributo | Descrição |
| ----------------- | ----------------------------------------------- |
| name | Identificador único do serviço. |
| description | Descrição para documentação. |
| method | Método HTTP da chamada externa. |
| route | Rota no gateway para chamada externa. |
| indexedResult | Se deve indexar o resultado. |
| responseHeaders | Headers fixos da resposta. |
| flow | Lista de etapas de orquestração para esta rota. |
Detalhes do flow
| Campo | Descrição |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| resultVariable | Variável que armazena o resultado da chamada externa. |
| skipErrors | Se true, continua o fluxo mesmo com erros. |
| cacheEnable | Se true, habilita cache para esta operação. |
| cacheTtl | TTL fixo do cache em segundos (fallback quando cacheTtlExpression não está definido ou falha). |
| cacheKey | Template Lodash interpolado contra o routeContext. Suporta deep paths ({{params.tenant}}, {{body.user.id}}, {{headers.x-tenant-id}}) e o helper {{queryHash}}, que produz um SHA-256 canônico da query string — chaves reordenadas (?a=1&b=2 vs ?b=2&a=1) resolvem para a mesma entrada. Quando omitido, o gateway usa o DNA da requisição como chave (OrchestrationFlow.getRequestDNA). |
| cacheTtlExpression | Template Lodash avaliado em runtime para derivar o TTL dinamicamente (ex.: {{credentialInfo.expirationTokenTime - 60}} para alinhar com a expiração de um token OAuth). Se a expressão falhar ou retornar valor inválido, o gateway loga stage=warn e cai no cacheTtl estático. |
| operation | Configuração da operação HTTP. |
Configuração operation
| Campo | Descrição |
| ------------------------ | --------------------------------------------------------- |
| clientName | Nome do cliente HTTP em mappingClients. |
| mergedHeaders | Se true, mescla todos os cabeçalhos de entrada. |
| headersTransformation | Função para transformar cabeçalhos. |
| requestTransformation | Função para transformar payload de request. |
| responseTransformation | Função para transformar a resposta recebida. |
| onError | Função acionada em caso de erro. |
| onSuccess | Função acionada em caso de sucesso. |
| headers | Headers estáticos extras para requisição. |
| type | Tipo da operação (http). |
| method | Método HTTP da chamada externa. |
| path | Path da rota externa, suportando templates de parâmetros. |
🏗️ Estrutura Esperada de Configuração
environment.js
module.exports = {
appName: process.env.appName || 'demo-api-gateway',
requestTimeout: process.env.requestTimeout || 20000,
requestPerSecond: process.env.requestPerSecond || 40,
memoryCheckInterval: process.env.memoryCheckInterval || 20000,
serverPort: process.env.serverPort || 9010,
logger: {
Console: {
level: process.env.loggerLevel || 'info'
}
},
enableRedis: true,
redisCache: {
reader: { host: 'localhost', port: 6379, connectTimeout: 5000 },
writer: { host: 'localhost', port: 6379, connectTimeout: 5000 }
},
enableElasticSearch: process.env.elasticEnable,
elasticSearch: {
indexName: process.env.elasticIndexName,
client: process.env.elasticClient,
credentials: { accessKeyId: process.env.elasticAccessKeyId, secretAccessKey: process.env.elasticSecretAccessKey },
host: process.env.elasticHost,
port: process.env.elasticPort
}
};| Atributo | Descrição |
| ----------------------------- | -------------------------------------------------------- |
| appName | Nome da aplicação exibido nos logs e métricas. |
| requestTimeout | Tempo (ms) para timeout de chamadas a serviços upstream. |
| requestPerSecond | Limite de requisições por segundo do gateway. |
| memoryCheckInterval | Intervalo (ms) para verificar uso de memória. |
| serverPort | Porta na qual o servidor HTTP irá escutar. |
| logger.Console.level | Nível de log para console (info, warn, error). |
| enableRedis | Ativa cache e throttling com Redis. |
| redisCache.reader.* | Configurações de conexão de leitura no Redis. |
| redisCache.writer.* | Configurações de conexão de escrita no Redis. |
| enableElasticSearch | Ativa integração com OpenSearch/ElasticSearch. |
| elasticSearch.indexName | Nome do índice para armazenamento de logs. |
| elasticSearch.client | Driver utilizado para conexão com OpenSearch. |
| elasticSearch.credentials.* | Credenciais de acesso ao OpenSearch. |
| elasticSearch.host | Host/URL do serviço OpenSearch. |
| elasticSearch.port | Porta do serviço OpenSearch. |
🔭 Endpoints administrativos & observabilidade
O gateway expõe um conjunto fixo de endpoints transversais — independentes do mappingServices configurado — para integração com painéis, scrape de métricas e probes de orquestrador.
| Endpoint | Auth | Para quê |
|---|---|---|
| GET /healthcheck | — | Liveness raso (legado), sempre { "success": true } |
| GET /health/live | — | Liveness probe (Kubernetes livenessProbe) |
| GET /health/ready | — | Readiness probe com checks reais de Redis, OpenSearch, Splunk e upstream clients. Default responde sempre 200 com status no body; use ?strict=true para o contrato 503-on-DEGRADED esperado pelo readinessProbe do K8s |
| GET /health | — | Mesmo payload e flag ?strict do /health/ready (compatível com painéis legados) |
| GET /monitor/health | — | Status raso { "status": "UP" } para load balancers |
| GET /monitor/info | — | Nome e versão da aplicação |
| GET /metrics | — | Snapshot JSON de processo, memória, event loop, gateway e Redis |
| GET /metrics/prometheus | — | Exposição Prometheus (formato exposition) — pronto para scrape |
| GET /monitor/requests | Basic Auth* | Busca paginada de requisições indexadas no OpenSearch |
| GET /monitor/requests/:id | Basic Auth* | Detalhe completo de uma requisição (incluindo body/headers) |
| GET /docs | Basic Auth* | UI Scalar consumindo /docs/openapi.yaml |
| GET /docs/swagger | Basic Auth* | UI Swagger clássica |
| GET /docs/openapi.yaml | Basic Auth* | OpenAPI 3.0.3 gerado a partir dos service groups |
| GET /docs/routes | Basic Auth* | Catálogo completo de rotas com flow detalhado e código-fonte de functions/mocks |
| * /admin/consumers | Basic Auth** | CRUD de Consumers (apps/parceiros/serviços) |
| * /admin/consumers/:id/keys | Basic Auth** | Emissão, listagem, rotação e revogação de API Keys |
* Quando application.documentation.enabled === true. Caso contrário, sem auth.
** Quando application.admin.enabled === true. Caso contrário, sem auth (apenas para dev).
Headers correlacionais
Toda resposta inclui automaticamente:
x-request-id— UUID por requisição (reusa o do cliente quando informado)x-request-uuid— alias legado dex-request-idx-trace-id— id de trace distribuído (W3C/Datadog/B3) quando há contexto válidox-request-duration— duração total da execução em ms
Documentação detalhada (com tipos TypeScript e exemplos
fetch/axiospara o front): vejadocs/api/.
docs/api/observability.md— health, metrics, Prometheus, correlation/trace headersdocs/api/monitor-requests.md— busca em OpenSearchdocs/api/docs-routes.md— explorer de rotas/flowsdocs/api/admin-consumers.md— Consumers, API Keys e middleware de validaçãodocs/api/rate-limit.md— Rate-limit per consumer (token bucket Lua/Redis + middleware)docs/api/quota.md— Quota engine per consumer (janeladay/month, contador atômico Lua/Redis + middleware)
▶️ Comandos Úteis
npm run build
npm run test
npm start🔑 Validação de Licença
Para uso em produção é obrigatória uma licença válida. Em ambientes de desenvolvimento e testes, a licença pode ser omitida.
A variável APP_KEY deve estar presente no ambiente:
export APP_KEY=minha-chave-da-licenca📜 Política de Licença
- Produção: exige licença.
- Dev/local: sem restrição.
- MIT.
📫 Suporte e Contato
- 🏢 Empresa: P4F
- 📧 E-mail: [email protected]
© 2025 P4F - Todos os direitos reservados.
