Express HTTP Proxy Middleware

2.1.2 · active · verified Tue Apr 21

express-http-proxy is an Express.js middleware designed for proxying incoming HTTP requests to a specified target host. It offers extensive customization through hooks, enabling developers to modify incoming requests before they reach the proxy target and decorate outgoing responses before they are returned to the client. The package is currently at version 2.1.2 and is actively maintained, having received updates like the significant v2.0.0 release that upgraded underlying dependencies and ensured compatibility with modern Node.js environments (16, 18, and 20). While not on a strict, frequent release cadence, updates are issued to address compatibility and dependency needs, especially for critical Node.js versions. Its key differentiator lies in its comprehensive set of configurable hooks for request and response transformation, making it suitable for scenarios requiring fine-grained control over proxy behavior within an Express application, such as API gateways or hiding internal service endpoints.

Common errors

Warnings

Install

Imports

Quickstart

This example sets up an Express server with `express-http-proxy` to forward requests from `/proxy` to `httpbin.org`. It demonstrates request/response logging, custom header injection, HTML response modification, and basic error handling.

import express from 'express';
import proxy from 'express-http-proxy';
import type { Request, Response, NextFunction } from 'express';

const app = express();
const PORT = process.env.PORT || 3000;
const PROXY_TARGET = process.env.PROXY_TARGET || 'https://httpbin.org'; // A public test service

// Middleware to log all incoming requests before proxying
app.use((req: Request, res: Response, next: NextFunction) => {
  console.log(`Incoming request: ${req.method} ${req.originalUrl}`);
  next();
});

// Configure the proxy middleware
app.use(
  '/proxy',
  proxy(PROXY_TARGET, {
    // Resolve the path for the proxied request
    proxyReqPathResolver: (req: Request) => {
      const resolvedPath = req.url.startsWith('/proxy') ? req.url.slice('/proxy'.length) : req.url;
      console.log(`Resolved proxy path to: ${resolvedPath}`);
      return resolvedPath;
    },
    // Decorate the request going to the proxy target
    decorateProxyReq: (proxyReq: any, req: Request) => {
      console.log(`Adding custom header to proxied request for ${req.path}`);
      proxyReq.setHeader('X-Proxy-By', 'express-http-proxy-example');
      return proxyReq;
    },
    // Decorate the response coming back from the proxy target
    decorateUserRes: (proxyRes: any, proxyResData: Buffer, userReq: Request, userRes: Response) => {
      console.log(`Received proxied response status: ${proxyRes.statusCode}`);
      // Example: modify response data (e.g., inject a footer)
      const data = proxyResData.toString('utf8');
      if (proxyRes.headers['content-type']?.includes('text/html')) {
        return data.replace('</body>', '<p><i>Proxied via express-http-proxy!</i></p></body>');
      }
      return proxyResData; // Return original data if not HTML
    },
    // Custom error handler for proxy errors
    proxyErrorHandler: (err: any, res: Response, next: NextFunction) => {
      console.error('Proxy error:', err);
      res.status(500).send('Proxy Error: Could not reach target.');
    }
  })
);

// Default route for non-proxied requests
app.get('/', (req: Request, res: Response) => {
  res.send('Hello from the main Express app! Try /proxy/get to use the proxy.');
});

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
  console.log(`Proxying requests from /proxy to ${PROXY_TARGET}`);
  console.log(`Try visiting http://localhost:${PORT}/proxy/get for a proxied request.`);
});

view raw JSON →