Proxy
Proxy and reverse proxy system in AzuraJS
Proxy System
AzuraJS offers a complete proxy/reverse proxy system to create API Gateways, microservices, and more. The proxy system is already included, no additional installation needed.
Basic Usage
Simple Proxy
const { AzuraClient } = require('azurajs');
const app = new AzuraClient();
// Proxy all /api/* requests to http://localhost:4000
app.proxy('/api', 'http://localhost:4000', {
pathRewrite: { '^/api': '' }
});
app.listen(3000);import { AzuraClient } from 'azurajs';
const app = new AzuraClient();
// Proxy all /api/* requests to http://localhost:4000
app.proxy('/api', 'http://localhost:4000', {
pathRewrite: { '^/api': '' }
});
app.listen(3000);Request example:
- Client makes:
GET http://localhost:3000/api/users - Proxy forwards to:
GET http://localhost:4000/users
With Path Rewrite
app.proxy('/api/v1', 'http://localhost:4000', {
pathRewrite: {
'^/api/v1': '/api', // Rewrites /api/v1 to /api
'/old': '/new' // Replaces /old with /new
}
});Proxy Options
ProxyOptions Interface
interface ProxyOptions {
// Target server URL
target: string;
// Path rewriting
pathRewrite?: Record<string, string>;
// Custom headers
headers?: Record<string, string>;
// Timeout in ms (default: 30000)
timeout?: number;
// Follow redirects
followRedirects?: boolean;
// Preserve original host
preserveHost?: boolean;
// Log level: "none" | "info" | "debug"
logLevel?: string;
// Callbacks
onProxyReq?: (proxyReq, req) => void;
onProxyRes?: (proxyRes, req, res) => void;
onError?: (err, req, res) => void;
}Example with All Options
app.proxy('/api', 'http://localhost:4000', {
// Path rewriting
pathRewrite: { '^/api': '' },
// Custom headers
headers: {
'X-Custom-Header': 'MyValue',
'Authorization': 'Bearer token123'
},
// 10 second timeout
timeout: 10000,
// Detailed logging
logLevel: 'debug',
// Modify request before sending
onProxyReq: (proxyReq, req) => {
console.log(`Proxying ${req.method} ${req.url}`);
proxyReq.setHeader('X-Request-ID', `req-${Date.now()}`);
},
// Modify response before sending to client
onProxyRes: (proxyRes, req, res) => {
console.log(`Response status: ${proxyRes.statusCode}`);
},
// Custom error handling
onError: (err, req, res) => {
console.error('Proxy error:', err);
res.status(502).json({ error: 'Gateway Error' });
}
});Use Cases
API Gateway
Centralize all your APIs in a single endpoint:
const gateway = new AzuraClient();
// Multiple services
gateway.proxy('/users', 'http://localhost:4001');
gateway.proxy('/products', 'http://localhost:4002');
gateway.proxy('/orders', 'http://localhost:4003');
gateway.listen(3000);Access:
/users/*→ User service on port 4001/products/*→ Product service on port 4002/orders/*→ Order service on port 4003
Proxy to External APIs
// Proxy to GitHub API
app.proxy('/github', 'https://api.github.com', {
pathRewrite: { '^/github': '' },
headers: {
'User-Agent': 'MyApp/1.0'
}
});
// Access: http://localhost:3000/github/users/octocatAuthentication at Gateway
// Authentication middleware
function authMiddleware({ req, res, next }) {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
// Validate token
if (!validateToken(token)) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
}
// Apply authentication before proxy
app.use('/api', authMiddleware);
app.proxy('/api', 'http://localhost:4000', {
pathRewrite: { '^/api': '' }
});Microservices with 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': '' }
});Error Handling
Common Errors
app.proxy('/api', 'http://localhost:4000', {
onError: (err, req, res) => {
if (err.code === 'ECONNREFUSED') {
return res.status(503).json({
error: 'Service Unavailable',
message: 'The service is temporarily unavailable'
});
}
if (err.code === 'ETIMEDOUT') {
return res.status(504).json({
error: 'Gateway Timeout',
message: 'The service took too long to respond'
});
}
res.status(502).json({
error: 'Bad Gateway',
message: 'Error processing the request'
});
}
});Complete Example
See complete examples at examples/servers/proxy:
- simple.js - Basic proxy
- microservices.js - Gateway for multiple services
