Node.js proxying made simple. Configure proxy middleware with ease for connect, express, next.js, hono and many more.
Powered by httpxy. A maintained version of http-proxy.
This page is showing documentation for version v4.x.x (release notes)
For older documentation:
Proxy /api requests to http://www.example.org
:bulb: Tip: Set the option changeOrigin to true for name-based virtual hosted sites.
// typescript
import express from 'express';
import type { NextFunction, Request, Response } from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import type { Filter, Options, RequestHandler } from 'http-proxy-middleware';
const app = express();
const proxyMiddleware = createProxyMiddleware<Request, Response>({
target: 'http://www.example.org/api',
changeOrigin: true,
});
app.use('/api', proxyMiddleware);
app.listen(3000);
// proxy and keep the same base path "/api"
// http://127.0.0.1:3000/api/foo/bar -> http://www.example.org/api/foo/bar
All httpxy options can be used, along with some extra http-proxy-middleware options.
pathFilter (string, []string, glob, []glob, function)pathRewrite (object/function)router (object/function)plugins (Array)ejectPlugins (boolean) default: falsedefinePlugin helperlogger (Object)httpxy eventshttpxy optionsnpm install --save-dev http-proxy-middleware
Create and configure a proxy middleware with: createProxyMiddleware(config).
import { createProxyMiddleware } from 'http-proxy-middleware';
const apiProxy = createProxyMiddleware({
target: 'http://www.example.org',
changeOrigin: true,
});
// 'apiProxy' is now ready to be used as middleware in a server.
options.changeOrigin: for virtual hosted sites
see full list of http-proxy-middleware configuration options
An example with express server.
// include dependencies
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
const app = express();
// create the proxy
/** @type {import('http-proxy-middleware').RequestHandler<import('express').Request, import('express').Response>} */
const exampleProxy = createProxyMiddleware({
target: 'http://www.example.org/api', // target host with the same base path
changeOrigin: true, // needed for virtual hosted sites
});
// mount `exampleProxy` in web server
app.use('/api', exampleProxy);
app.listen(3000);
If you want to use the server's app.use path parameter to match requests.
Use pathFilter option to further include/exclude requests which you want to proxy.
app.use(
createProxyMiddleware({
target: 'http://www.example.org/api',
changeOrigin: true,
pathFilter: '/api/proxy-only-this-path',
}),
);
app.use documentation:
http-proxy-middleware options:
pathFilter (string, []string, glob, []glob, function)Narrow down which requests should be proxied. The path used for filtering is the request.url pathname. In Express, this is the path relative to the mount-point of the proxy.
createProxyMiddleware({...}) - matches any path, all requests will be proxied when pathFilter is not configured.createProxyMiddleware({ pathFilter: '/api', ...}) - matches paths starting with /api
multiple path matching
createProxyMiddleware({ pathFilter: ['/api', '/ajax', '/someotherpath'], ...})
wildcard path matching
For fine-grained control you can use wildcard matching. Glob pattern matching is done by micromatch. Visit micromatch or glob for more globbing examples.
- createProxyMiddleware({ pathFilter: '**', ...}) matches any path, all requests will be proxied.
- createProxyMiddleware({ pathFilter: '**/*.html', ...}) matches any path which ends with .html
- createProxyMiddleware({ pathFilter: '/*.html', ...}) matches paths directly under path-absolute
- createProxyMiddleware({ pathFilter: '/api/**/*.html', ...}) matches requests ending with .html in the path of /api
- createProxyMiddleware({ pathFilter: ['/api/**', '/ajax/**'], ...}) combine multiple patterns
- createProxyMiddleware({ pathFilter: ['/api/**', '!**/bad.json'], ...}) exclusion
Note: In multiple path matching, you cannot use string paths and wildcard paths together.
For full control you can provide a custom function to determine which requests should be proxied or not.
```javascript /* * @return {Boolean} / const pathFilter = function (path, req) { return path.match('^/api') && req.method === 'GET'; };
const apiProxy = createProxyMiddleware({ target: 'http://www.example.org', pathFilter: pathFilter, }); ```
pathRewrite (object/function)Rewrite target's url path. Object-keys will be used as RegExp to match paths.
// rewrite path
pathRewrite: {'^/old/api' : '/new/api'}
// remove path
pathRewrite: {'^/remove/api' : ''}
// add base path
pathRewrite: {'^/' : '/basepath/'}
// custom rewriting
pathRewrite: function (path, req, res, options) { return path.replace('/api', '/base/api') }
// custom rewriting, returning Promise
pathRewrite: async function (path, req, res, options) {
const should_add_something = await httpRequestToDecideSomething(path);
if (should_add_something) path += "something";
return path;
}
// `res` is undefined in WebSocket upgrade flows.
router (object/function)Re-target option.target for specific requests.
// Use `host` and/or `path` to match requests. First match will be used.
// The order of the configuration matters.
router: {
'integration.localhost:3000' : 'http://127.0.0.1:8001', // host only
'staging.localhost:3000' : 'http://127.0.0.1:8002', // host only
'localhost:3000/api' : 'http://127.0.0.1:8003', // host + path
'/rest' : 'http://127.0.0.1:8004' // path only
}
// Custom router function (string target)
router: function(req, res, options) {
return 'http://127.0.0.1:8004';
}
// Custom router function (target object)
router: function(req, res, options) {
return {
protocol: 'https:', // The : is required
host: '127.0.0.1',
port: 8004
};
}
// Asynchronous router function which returns promise
router: async function(req, res, options) {
const url = await doSomeIO();
return url;
}
// NOTE: `res` is undefined in WebSocket upgrade flows.
plugins (Array)const simpleRequestLogger = (proxyServer, options) => {
proxyServer.on('proxyReq', (proxyReq, req, res) => {
console.log(`[HPM] [${req.method}] ${req.url}`); // outputs: [HPM] GET /users
});
},
const config = {
target: `http://example.org`,
changeOrigin: true,
plugins: [simpleRequestLogger],
};
ejectPlugins (boolean) default: falseIf you're not satisfied with the pre-configured plugins, you can eject them by configuring ejectPlugins: true.
NOTE: register your own error handlers to prevent server from crashing.
// eject default plugins and manually add them back
import {
debugProxyErrorsPlugin, // subscribe to proxy errors to prevent server from crashing
errorResponsePlugin, // return 5xx response on proxy error
loggerPlugin, // log proxy events to a logger (ie. console)
proxyEventsPlugin, // implements the "on:" option
} from 'http-proxy-middleware';
createProxyMiddleware({
target: `http://example.org`,
changeOrigin: true,
ejectPlugins: true,
plugins: [debugProxyErrorsPlugin, loggerPlugin, errorResponsePlugin, proxyEventsPlugin],
});
definePlugin helperCreate your own http-proxy-middleware plugin.
(Default plugins are created with definePlugin)
import { createProxyMiddleware, definePlugin } from 'http-proxy-middleware';
const myPlugin = definePlugin((proxyServer, options) => {
// plugin implementation
});
// use configure and use plugin
createProxyMiddleware({
target: `http://example.org`,
plugins: [myPlugin],
});
logger (Object)Configure a logger to output information from http-proxy-middleware: ie. console, winston, pino, bunyan, log4js, etc...
Only info, warn, error are used internally for compatibility across different loggers.
If you use winston, make sure to enable interpolation: https://github.com/winstonjs/winston#string-interpolation
See also logger recipes (recipes/logger.md) for more details.
createProxyMiddleware({
logger: console,
});
httpxy eventsSubscribe to httpxy events with the on option:
createProxyMiddleware({
target: 'http://www.example.org',
on: {
proxyReq: (proxyReq, req, res) => {
/* handle proxyReq */
},
proxyRes: (proxyRes, req, res) => {
/* handle proxyRes */
},
error: (err, req, res) => {
/* handle error */
},
},
});
error event for custom error handling.javascript
function onError(err, req, res, target) {
res.writeHead(500, {
'Content-Type': 'text/plain',
});
res.end('Something went wrong. And we are reporting a custom error message.');
}
proxyRes event.javascript
function onProxyRes(proxyRes, req, res) {
proxyRes.headers['x-added'] = 'foobar'; // add new header to response
delete proxyRes.headers['x-removed']; // remove header from response
}
proxyReq event.javascript
function onProxyReq(proxyReq, req, res) {
// add custom header to request
proxyReq.setHeader('x-added', 'foobar');
// or log the req
}
proxyReqWs event.javascript
function onProxyReqWs(proxyReq, req, socket, options, head) {
// add custom header
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
}
open event.javascript
function onOpen(proxySocket) {
// listen for messages coming FROM the target here
proxySocket.on('data', hybridParseAndLogMessage);
}
close event.javascript
function onClose(res, socket, head) {
// view disconnected websocket connections
console.log('Client disconnected');
}
httpxy optionsThe following options are provided by the underlying httpxy library.
$ claude mcp add http-proxy-middleware \
-- python -m otcore.mcp_server <graph>