Proxy
Sistema de proxy e reverse proxy no AzuraJS
Sistema de Proxy
O AzuraJS oferece um sistema completo de proxy/reverse proxy para criar API Gateways, microsserviços e muito mais. O sistema de proxy já vem incluído, não precisa instalar nada adicional.
Uso Básico
Proxy Simples
const { AzuraClient } = require('azurajs');
const app = new AzuraClient();
// Faz proxy de todas as requisições /api/* para http://localhost:4000
app.proxy('/api', 'http://localhost:4000', {
pathRewrite: { '^/api': '' }
});
app.listen(3000);import { AzuraClient } from 'azurajs';
const app = new AzuraClient();
// Faz proxy de todas as requisições /api/* para http://localhost:4000
app.proxy('/api', 'http://localhost:4000', {
pathRewrite: { '^/api': '' }
});
app.listen(3000);Exemplo de requisição:
- Cliente faz:
GET http://localhost:3000/api/users - Proxy encaminha para:
GET http://localhost:4000/users
Com Path Rewrite
app.proxy('/api/v1', 'http://localhost:4000', {
pathRewrite: {
'^/api/v1': '/api', // Reescreve /api/v1 para /api
'/old': '/new' // Substitui /old por /new
}
});Opções do Proxy
Interface ProxyOptions
interface ProxyOptions {
// URL do servidor de destino
target: string;
// Reescrever paths
pathRewrite?: Record<string, string>;
// Headers customizados
headers?: Record<string, string>;
// Timeout em ms (padrão: 30000)
timeout?: number;
// Seguir redirects
followRedirects?: boolean;
// Manter host original
preserveHost?: boolean;
// Nível de log: "none" | "info" | "debug"
logLevel?: string;
// Callbacks
onProxyReq?: (proxyReq, req) => void;
onProxyRes?: (proxyRes, req, res) => void;
onError?: (err, req, res) => void;
}Exemplo com Todas as Opções
app.proxy('/api', 'http://localhost:4000', {
// Reescrever path
pathRewrite: { '^/api': '' },
// Headers customizados
headers: {
'X-Custom-Header': 'MyValue',
'Authorization': 'Bearer token123'
},
// Timeout de 10 segundos
timeout: 10000,
// Log detalhado
logLevel: 'debug',
// Modificar requisição antes de enviar
onProxyReq: (proxyReq, req) => {
console.log(`Proxying ${req.method} ${req.url}`);
proxyReq.setHeader('X-Request-ID', `req-${Date.now()}`);
},
// Modificar resposta antes de enviar ao cliente
onProxyRes: (proxyRes, req, res) => {
console.log(`Response status: ${proxyRes.statusCode}`);
},
// Tratamento de erros customizado
onError: (err, req, res) => {
console.error('Proxy error:', err);
res.status(502).json({ error: 'Gateway Error' });
}
});Casos de Uso
API Gateway
Centralize todas as suas APIs em um único endpoint:
const gateway = new AzuraClient();
// Múltiplos serviços
gateway.proxy('/users', 'http://localhost:4001');
gateway.proxy('/products', 'http://localhost:4002');
gateway.proxy('/orders', 'http://localhost:4003');
gateway.listen(3000);Acesso:
/users/*→ Serviço de usuários na porta 4001/products/*→ Serviço de produtos na porta 4002/orders/*→ Serviço de pedidos na porta 4003
Proxy para APIs Externas
// Proxy para GitHub API
app.proxy('/github', 'https://api.github.com', {
pathRewrite: { '^/github': '' },
headers: {
'User-Agent': 'MyApp/1.0'
}
});
// Acesse: http://localhost:3000/github/users/octocatAutenticação no Gateway
// Middleware de autenticação
function authMiddleware({ req, res, next }) {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
// Validar token
if (!validateToken(token)) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
}
// Aplicar autenticação antes do proxy
app.use('/api', authMiddleware);
app.proxy('/api', 'http://localhost:4000', {
pathRewrite: { '^/api': '' }
});Microserviços com Cache
const cache = new Map();
function cacheMiddleware({ req, res, next }) {
const key = req.url;
if (cache.has(key)) {
return res.json(cache.get(key));
}
const originalJson = res.json.bind(res);
res.json = (data) => {
cache.set(key, data);
return originalJson(data);
};
next();
}
app.use('/api/posts', cacheMiddleware);
app.proxy('/api/posts', 'https://jsonplaceholder.typicode.com', {
pathRewrite: { '^/api': '' }
});Tratamento de Erros
Erros Comuns
app.proxy('/api', 'http://localhost:4000', {
onError: (err, req, res) => {
if (err.code === 'ECONNREFUSED') {
return res.status(503).json({
error: 'Service Unavailable',
message: 'O serviço está temporariamente indisponível'
});
}
if (err.code === 'ETIMEDOUT') {
return res.status(504).json({
error: 'Gateway Timeout',
message: 'O serviço demorou muito para responder'
});
}
res.status(502).json({
error: 'Bad Gateway',
message: 'Erro ao processar a requisição'
});
}
});Exemplo Completo
Veja exemplos completos em examples/servers/proxy:
- simple.js - Proxy básico
- microservices.js - Gateway para múltiplos serviços
