Working with Proxy and Load Balancing
1. Installing http-proxy-middleware
2. Creating Proxy Middleware
Example: Basic proxy
import { createProxyMiddleware } from "http-proxy-middleware";
app.use("/api", createProxyMiddleware({
target: "http://upstream:3001",
changeOrigin: true
}));
3. Configuring Target URL
| Option | Purpose |
|---|---|
| target | Upstream URL |
| changeOrigin | Rewrite Host header to target |
| secure | Validate TLS cert (default true) |
| xfwd | Add X-Forwarded-* headers |
4. Enabling Path Rewriting
Example: Strip prefix
createProxyMiddleware({
target: "http://upstream:3001",
pathRewrite: { "^/api/v1": "" }
});
5. Handling WebSocket Proxying
Example: ws: true
const wsProxy = createProxyMiddleware({ target: "ws://realtime:3002", ws: true });
app.use("/ws", wsProxy);
server.on("upgrade", wsProxy.upgrade);
6. Setting Proxy Timeout
Example: timeouts
createProxyMiddleware({
target: "http://upstream",
proxyTimeout: 30_000, // upstream response
timeout: 30_000 // incoming socket
});
7. Implementing Load Balancing Logic
Example: Round-robin router
const upstreams = ["http://api-1:3001","http://api-2:3001","http://api-3:3001"];
let i = 0;
app.use("/api", createProxyMiddleware({
router: () => upstreams[i++ % upstreams.length],
changeOrigin: true
}));
Note: For real production load balancing prefer dedicated layers (Nginx, HAProxy, Envoy, AWS ALB) over Express.
8. Using Router Function
Example: Route by tenant
app.use("/api", createProxyMiddleware({
router: (req) => `http://${req.get("X-Tenant-Id")}.api.internal:3001`,
changeOrigin: true
}));
9. Handling Proxy Errors
Example: onError
createProxyMiddleware({
target: "http://upstream",
on: {
error: (err, req, res) => {
logger.error({ err }, "Proxy error");
if (!res.headersSent) res.status(502).json({ error: "Upstream unavailable" });
}
}
});