Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0b30c5d

Browse filesBrowse files
authored
feat(option): refactor context to pathFilter option [BREAKING CHANGE] (#722)
1 parent 1540dac commit 0b30c5d
Copy full SHA for 0b30c5d
Expand file treeCollapse file tree

22 files changed

+558
-609
lines changed

‎README.md

Copy file name to clipboardExpand all lines: README.md
+124-110Lines changed: 124 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,20 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
5454

5555
## Table of Contents <!-- omit in toc -->
5656

57+
<!-- // spell-checker:disable -->
58+
5759
- [Install](#install)
5860
- [Core concept](#core-concept)
59-
- [Example](#example)
61+
- [Express Server Example](#express-server-example)
6062
- [app.use(path, proxy)](#appusepath-proxy)
61-
- [Context matching](#context-matching)
6263
- [Options](#options)
63-
- [http-proxy-middleware options](#http-proxy-middleware-options)
64-
- [http-proxy events](#http-proxy-events)
65-
- [http-proxy options](#http-proxy-options)
64+
- [`pathFilter` (string, []string, glob, []glob, function)](#pathfilter-string-string-glob-glob-function)
65+
- [`pathRewrite` (object/function)](#pathrewrite-objectfunction)
66+
- [`router` (object/function)](#router-objectfunction)
67+
- [`logLevel` (string)](#loglevel-string)
68+
- [`logProvider` (function)](#logprovider-function)
69+
- [`http-proxy` events](#http-proxy-events)
70+
- [`http-proxy` options](#http-proxy-options)
6671
- [WebSocket](#websocket)
6772
- [External WebSocket upgrade](#external-websocket-upgrade)
6873
- [Intercept and manipulate requests](#intercept-and-manipulate-requests)
@@ -74,36 +79,36 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
7479
- [Changelog](#changelog)
7580
- [License](#license)
7681

82+
<!-- // spell-checker:enable -->
83+
7784
## Install
7885

79-
```bash
80-
$ npm install --save-dev http-proxy-middleware
86+
```shell
87+
npm install --save-dev http-proxy-middleware
8188
```
8289

8390
## Core concept
8491

85-
Proxy middleware configuration.
86-
87-
#### createProxyMiddleware([context,] config)
92+
Create and configure a proxy middleware with: `createProxyMiddleware(config)`.
8893

8994
```javascript
9095
const { createProxyMiddleware } = require('http-proxy-middleware');
9196

92-
const apiProxy = createProxyMiddleware('/api', { target: 'http://www.example.org' });
93-
// \____/ \_____________________________/
94-
// | |
95-
// context options
97+
const apiProxy = createProxyMiddleware({
98+
pathFilter: '/api',
99+
target: 'http://www.example.org',
100+
});
96101

97102
// 'apiProxy' is now ready to be used as middleware in a server.
98103
```
99104

100-
- **context**: Determine which requests should be proxied to the target host.
101-
(more on [context matching](#context-matching))
105+
- **options.pathFilter**: Determine which requests should be proxied to the target host.
106+
(more on [path filter](#path-filter))
102107
- **options.target**: target host to proxy to. _(protocol + host)_
103108

104-
(full list of [`http-proxy-middleware` configuration options](#options))
109+
- see full list of [`http-proxy-middleware` configuration options](#options)
105110

106-
## Example
111+
## Express Server Example
107112

108113
An example with `express` server.
109114

@@ -129,7 +134,7 @@ const options = {
129134
},
130135
};
131136

132-
// create the proxy (without context)
137+
// create the proxy
133138
const exampleProxy = createProxyMiddleware(options);
134139

135140
// mount `exampleProxy` in web server
@@ -140,8 +145,8 @@ app.listen(3000);
140145

141146
### app.use(path, proxy)
142147

143-
If you want to use the server's `app.use` `path` parameter to match requests;
144-
Create and mount the proxy without the http-proxy-middleware `context` parameter:
148+
If you want to use the server's `app.use` `path` parameter to match requests.
149+
Use `pathFilter` option to further include/exclude requests which you want to proxy.
145150

146151
```javascript
147152
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
@@ -153,11 +158,15 @@ app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', change
153158
- connect: https://github.com/senchalabs/connect#mount-middleware
154159
- polka: https://github.com/lukeed/polka#usebase-fn
155160

156-
## Context matching
161+
## Options
162+
163+
http-proxy-middleware options:
164+
165+
### `pathFilter` (string, []string, glob, []glob, function)
157166

158-
Providing an alternative way to decide which requests should be proxied; In case you are not able to use the server's [`path` parameter](http://expressjs.com/en/4x/api.html#app.use) to mount the proxy or when you need more flexibility.
167+
Decide which requests should be proxied; In case you are not able to use the server's [`path` parameter](http://expressjs.com/en/4x/api.html#app.use) to mount the proxy or when you need more flexibility.
159168

160-
[RFC 3986 `path`](https://tools.ietf.org/html/rfc3986#section-3.3) is used for context matching.
169+
[RFC 3986 `path`](https://tools.ietf.org/html/rfc3986#section-3.3) is used in `pathFilter`.
161170

162171
```ascii
163172
foo://example.com:8042/over/there?name=ferret#nose
@@ -169,23 +178,22 @@ Providing an alternative way to decide which requests should be proxied; In case
169178
- **path matching**
170179

171180
- `createProxyMiddleware({...})` - matches any path, all requests will be proxied.
172-
- `createProxyMiddleware('/', {...})` - matches any path, all requests will be proxied.
173-
- `createProxyMiddleware('/api', {...})` - matches paths starting with `/api`
181+
- `createProxyMiddleware({ pathFilter: '/api', ...})` - matches paths starting with `/api`
174182

175183
- **multiple path matching**
176184

177-
- `createProxyMiddleware(['/api', '/ajax', '/someotherpath'], {...})`
185+
- `createProxyMiddleware({ pathFilter: ['/api', '/ajax', '/someotherpath'], ...})`
178186

179187
- **wildcard path matching**
180188

181189
For fine-grained control you can use wildcard matching. Glob pattern matching is done by _micromatch_. Visit [micromatch](https://www.npmjs.com/package/micromatch) or [glob](https://www.npmjs.com/package/glob) for more globbing examples.
182190

183-
- `createProxyMiddleware('**', {...})` matches any path, all requests will be proxied.
184-
- `createProxyMiddleware('**/*.html', {...})` matches any path which ends with `.html`
185-
- `createProxyMiddleware('/*.html', {...})` matches paths directly under path-absolute
186-
- `createProxyMiddleware('/api/**/*.html', {...})` matches requests ending with `.html` in the path of `/api`
187-
- `createProxyMiddleware(['/api/**', '/ajax/**'], {...})` combine multiple patterns
188-
- `createProxyMiddleware(['/api/**', '!**/bad.json'], {...})` exclusion
191+
- `createProxyMiddleware({ pathFilter: '**', ...})` matches any path, all requests will be proxied.
192+
- `createProxyMiddleware({ pathFilter: '**/*.html', ...})` matches any path which ends with `.html`
193+
- `createProxyMiddleware({ pathFilter: '/*.html', ...})` matches paths directly under path-absolute
194+
- `createProxyMiddleware({ pathFilter: '/api/**/*.html', ...})` matches requests ending with `.html` in the path of `/api`
195+
- `createProxyMiddleware({ pathFilter: ['/api/**', '/ajax/**'], ...})` combine multiple patterns
196+
- `createProxyMiddleware({ pathFilter: ['/api/**', '!**/bad.json'], ...})` exclusion
189197

190198
**Note**: In multiple path matching, you cannot use string paths and wildcard paths together.
191199

@@ -197,104 +205,110 @@ Providing an alternative way to decide which requests should be proxied; In case
197205
/**
198206
* @return {Boolean}
199207
*/
200-
const filter = function (pathname, req) {
201-
return pathname.match('^/api') && req.method === 'GET';
208+
const filter = function (path, req) {
209+
return path.match('^/api') && req.method === 'GET';
202210
};
203211

204212
const apiProxy = createProxyMiddleware(filter, {
205213
target: 'http://www.example.org',
206214
});
207215
```
208216

209-
## Options
217+
### `pathRewrite` (object/function)
210218

211-
### http-proxy-middleware options
219+
Rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
212220

213-
- **option.pathRewrite**: object/function, rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
221+
```javascript
222+
// rewrite path
223+
pathRewrite: {'^/old/api' : '/new/api'}
214224

215-
```javascript
216-
// rewrite path
217-
pathRewrite: {'^/old/api' : '/new/api'}
225+
// remove path
226+
pathRewrite: {'^/remove/api' : ''}
218227

219-
// remove path
220-
pathRewrite: {'^/remove/api' : ''}
228+
// add base path
229+
pathRewrite: {'^/' : '/basepath/'}
221230

222-
// add base path
223-
pathRewrite: {'^/' : '/basepath/'}
231+
// custom rewriting
232+
pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
224233

225-
// custom rewriting
226-
pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
234+
// custom rewriting, returning Promise
235+
pathRewrite: async function (path, req) {
236+
const should_add_something = await httpRequestToDecideSomething(path);
237+
if (should_add_something) path += "something";
238+
return path;
239+
}
240+
```
227241

228-
// custom rewriting, returning Promise
229-
pathRewrite: async function (path, req) {
230-
const should_add_something = await httpRequestToDecideSomething(path);
231-
if (should_add_something) path += "something";
232-
return path;
233-
}
234-
```
242+
### `router` (object/function)
235243

236-
- **option.router**: object/function, re-target `option.target` for specific requests.
244+
Re-target `option.target` for specific requests.
237245

238-
```javascript
239-
// Use `host` and/or `path` to match requests. First match will be used.
240-
// The order of the configuration matters.
241-
router: {
242-
'integration.localhost:3000' : 'http://localhost:8001', // host only
243-
'staging.localhost:3000' : 'http://localhost:8002', // host only
244-
'localhost:3000/api' : 'http://localhost:8003', // host + path
245-
'/rest' : 'http://localhost:8004' // path only
246-
}
246+
```javascript
247+
// Use `host` and/or `path` to match requests. First match will be used.
248+
// The order of the configuration matters.
249+
router: {
250+
'integration.localhost:3000' : 'http://localhost:8001', // host only
251+
'staging.localhost:3000' : 'http://localhost:8002', // host only
252+
'localhost:3000/api' : 'http://localhost:8003', // host + path
253+
'/rest' : 'http://localhost:8004' // path only
254+
}
255+
256+
// Custom router function (string target)
257+
router: function(req) {
258+
return 'http://localhost:8004';
259+
}
260+
261+
// Custom router function (target object)
262+
router: function(req) {
263+
return {
264+
protocol: 'https:', // The : is required
265+
host: 'localhost',
266+
port: 8004
267+
};
268+
}
247269

248-
// Custom router function (string target)
249-
router: function(req) {
250-
return 'http://localhost:8004';
251-
}
270+
// Asynchronous router function which returns promise
271+
router: async function(req) {
272+
const url = await doSomeIO();
273+
return url;
274+
}
275+
```
252276

253-
// Custom router function (target object)
254-
router: function(req) {
255-
return {
256-
protocol: 'https:', // The : is required
257-
host: 'localhost',
258-
port: 8004
259-
};
260-
}
277+
### `logLevel` (string)
261278

262-
// Asynchronous router function which returns promise
263-
router: async function(req) {
264-
const url = await doSomeIO();
265-
return url;
266-
}
267-
```
279+
Default: `'info'`
268280

269-
- **option.logLevel**: string, ['debug', 'info', 'warn', 'error', 'silent']. Default: `'info'`
281+
Values: ['debug', 'info', 'warn', 'error', 'silent'].
270282

271-
- **option.logProvider**: function, modify or replace log provider. Default: `console`.
283+
### `logProvider` (function)
272284

273-
```javascript
274-
// simple replace
275-
function logProvider(provider) {
276-
// replace the default console log provider.
277-
return require('winston');
278-
}
279-
```
285+
Modify or replace log provider. Default: `console`.
280286

281-
```javascript
282-
// verbose replacement
283-
function logProvider(provider) {
284-
const logger = new (require('winston').Logger)();
285-
286-
const myCustomProvider = {
287-
log: logger.log,
288-
debug: logger.debug,
289-
info: logger.info,
290-
warn: logger.warn,
291-
error: logger.error,
292-
};
293-
return myCustomProvider;
294-
}
295-
```
287+
```javascript
288+
// simple replace
289+
function logProvider(provider) {
290+
// replace the default console log provider.
291+
return require('winston');
292+
}
293+
```
294+
295+
```javascript
296+
// verbose replacement
297+
function logProvider(provider) {
298+
const logger = new (require('winston').Logger)();
299+
300+
const myCustomProvider = {
301+
log: logger.log,
302+
debug: logger.debug,
303+
info: logger.info,
304+
warn: logger.warn,
305+
error: logger.error,
306+
};
307+
return myCustomProvider;
308+
}
309+
```
296310

297-
### http-proxy events
311+
## `http-proxy` events
298312

299313
Subscribe to [http-proxy events](https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events):
300314

@@ -355,7 +369,7 @@ Subscribe to [http-proxy events](https://github.com/nodejitsu/node-http-proxy#li
355369
}
356370
```
357371

358-
### http-proxy options
372+
## `http-proxy` options
359373

360374
The following options are provided by the underlying [http-proxy](https://github.com/nodejitsu/node-http-proxy#options) library.
361375

@@ -431,15 +445,15 @@ The following options are provided by the underlying [http-proxy](https://github
431445

432446
```javascript
433447
// verbose api
434-
createProxyMiddleware('/', { target: 'http://echo.websocket.org', ws: true });
448+
createProxyMiddleware({ pathFilter: '/', target: 'http://echo.websocket.org', ws: true });
435449
```
436450

437451
### External WebSocket upgrade
438452

439453
In the previous WebSocket examples, http-proxy-middleware relies on a initial http request in order to listen to the http `upgrade` event. If you need to proxy WebSockets without the initial http request, you can subscribe to the server's http `upgrade` event manually.
440454

441455
```javascript
442-
const wsProxy = createProxyMiddleware('ws://echo.websocket.org', { changeOrigin: true });
456+
const wsProxy = createProxyMiddleware({ target: 'ws://echo.websocket.org', changeOrigin: true });
443457

444458
const app = express();
445459
app.use(wsProxy);

‎examples/browser-sync/index.js

Copy file name to clipboardExpand all lines: examples/browser-sync/index.js
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ const { createProxyMiddleware } = require('../../dist'); // require('http-proxy-
77
/**
88
* Configure proxy middleware
99
*/
10-
const jsonPlaceholderProxy = createProxyMiddleware('/users', {
10+
const jsonPlaceholderProxy = createProxyMiddleware({
1111
target: 'http://jsonplaceholder.typicode.com',
12+
pathFilter: '/users',
1213
changeOrigin: true, // for vhosted sites, changes host header to match to target's host
1314
logLevel: 'debug',
1415
});

‎examples/websocket/index.html

Copy file name to clipboardExpand all lines: examples/websocket/index.html
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<body>
2222
<h2>WebSocket demo</h2>
2323

24-
<p>Proxy <code>ws://localhost:3000</code> to <code>ws://echo.websocket.org</code></p>
24+
<p>Proxy <code>ws://localhost:3000</code> to <code>ws://ws.ifelse.io</code></p>
2525

2626
<fieldset id="configuration">
2727
<p>

‎examples/websocket/index.js

Copy file name to clipboardExpand all lines: examples/websocket/index.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ const { createProxyMiddleware } = require('../../dist'); // require('http-proxy-
77
/**
88
* Configure proxy middleware
99
*/
10-
const wsProxy = createProxyMiddleware('/', {
11-
target: 'http://echo.websocket.org',
10+
const wsProxy = createProxyMiddleware({
11+
target: 'http://ws.ifelse.io',
1212
// pathRewrite: {
1313
// '^/websocket' : '/socket', // rewrite path.
1414
// '^/removepath' : '' // remove path.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.