Skip to content

Commit cdfe934

Browse files
authored
feat(legacyCreateProxyMiddleware): adapter with v2 behaviour (#754)
* fix(error event): user error event handler replaces default error response handler * feat(legacyCreateProxyMiddleware): adapter with legacy behavior * test(on.error): test custom error handler * chore(typescript): deprecate LegacyOptions * docs: minor doc improvements
1 parent 397aed3 commit cdfe934

19 files changed

+624
-28
lines changed

MIGRATION.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# Migration guide
2+
3+
- [v2 to v3 adapter](#v2-to-v3-adapter)
4+
- [`legacyCreateProxyMiddleware`](#legacycreateproxymiddleware)
5+
- [v3 breaking changes](#v3-breaking-changes)
6+
- [Removed `req.url` patching](#removed-requrl-patching)
7+
- [`pathRewrite` (potential behavior change)](#pathrewrite-potential-behavior-change)
8+
- [Removed "shorthand" usage](#removed-shorthand-usage)
9+
- [Removed `context` argument](#removed-context-argument)
10+
- [Removed `logProvider` and `logLevel` options](#removed-logprovider-and-loglevel-options)
11+
- [Refactored proxy events](#refactored-proxy-events)
12+
13+
## v2 to v3 adapter
14+
15+
### `legacyCreateProxyMiddleware`
16+
17+
Use the adapter to use v3 with minimal changes to your v2 implementation.
18+
19+
NOTE: `legacyCreateProxyMiddleware` will be removed in a future version.
20+
21+
```js
22+
// before
23+
const { createProxyMiddleware } = require('http-proxy-middleware');
24+
25+
createProxyMiddleware(...);
26+
27+
// after
28+
const { legacyCreateProxyMiddleware } = require('http-proxy-middleware');
29+
30+
legacyCreateProxyMiddleware(...);
31+
```
32+
33+
```ts
34+
// before
35+
import { createProxyMiddleware, Options } from 'http-proxy-middleware';
36+
37+
createProxyMiddleware(...);
38+
39+
// after
40+
import { legacyCreateProxyMiddleware, LegacyOptions } from 'http-proxy-middleware';
41+
42+
legacyCreateProxyMiddleware(...);
43+
```
44+
45+
## v3 breaking changes
46+
47+
### Removed `req.url` patching
48+
49+
```js
50+
// before
51+
app.use('/user', proxy({ target: 'http://www.example.org' }));
52+
53+
// after
54+
app.use('/user', proxy({ target: 'http://www.example.org/user' }));
55+
```
56+
57+
### `pathRewrite` (potential behavior change)
58+
59+
Related to removal of [`req.url` patching](#removed-requrl-patching).
60+
61+
`pathRewrite` now only rewrites the `path` after the mount point.
62+
63+
It was common to rewrite the `basePath` with the `pathRewrite` option:
64+
65+
```js
66+
// before
67+
app.use('/user', proxy({
68+
target: 'http://www.example.org'
69+
pathRewrite: { '^/user': '/secret' }
70+
}));
71+
72+
// after
73+
app.use('/user', proxy({ target: 'http://www.example.org/secret' }));
74+
```
75+
76+
When proxy is mounted at the root, `pathRewrite` should still work as in v2.
77+
78+
```js
79+
// not affected
80+
app.use(proxy({
81+
target: 'http://www.example.org'
82+
pathRewrite: { '^/user': '/secret' }
83+
}));
84+
```
85+
86+
### Removed "shorthand" usage
87+
88+
Specify the `target` option.
89+
90+
```js
91+
// before
92+
createProxyMiddleware('http:/www.example.org');
93+
94+
// after
95+
createProxyMiddleware({ target: 'http:/www.example.org' });
96+
```
97+
98+
### Removed `context` argument
99+
100+
The `context` argument has been moved to option: `pathFilter`.
101+
102+
Functionality did not change.
103+
104+
See [recipes/pathFilter.md](./recipes/pathFilter.md) for more information.
105+
106+
```js
107+
// before
108+
createProxyMiddleware('/path', { target: 'http://www.example.org' });
109+
110+
// after
111+
createProxyMiddleware({
112+
target: 'http://www.example.org',
113+
pathFilter: '/path',
114+
});
115+
```
116+
117+
### Removed `logProvider` and `logLevel` options
118+
119+
Use your external logging library to _log_ and control the logging _level_.
120+
121+
Only `info`, `warn`, `error` are used internally for compatibility across different loggers.
122+
123+
If you use `winston`, make sure to enable interpolation: <https://github.com/winstonjs/winston#string-interpolation>
124+
125+
See [recipes/logger.md](./recipes/logger.md) for more information.
126+
127+
```js
128+
// new
129+
createProxyMiddleware({
130+
target: 'http://www.example.org',
131+
logger: console,
132+
});
133+
```
134+
135+
### Refactored proxy events
136+
137+
See [recipes/proxy-events.md](./recipes/proxy-events.md) for more information.
138+
139+
```js
140+
// before
141+
createProxyMiddleware({
142+
target: 'http://www.example.org',
143+
onError: () => {},
144+
onProxyReq: () => {},
145+
onProxyRes: () => {},
146+
onProxyReqWs: () => {},
147+
onOpen: () => {},
148+
onClose: () => {},
149+
});
150+
151+
// after
152+
createProxyMiddleware({
153+
target: 'http://www.example.org',
154+
on: {
155+
error: () => {},
156+
proxyReq: () => {},
157+
proxyRes: () => {},
158+
proxyReqWs: () => {},
159+
open: () => {},
160+
close: () => {},
161+
},
162+
});
163+
```

README.md

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ Powered by the popular Nodejitsu [`http-proxy`](https://github.com/nodejitsu/nod
1111

1212
## ⚠️ Note <!-- omit in toc -->
1313

14-
This page is showing documentation for version v2.x.x ([release notes](https://github.com/chimurai/http-proxy-middleware/releases))
14+
This page is showing documentation for version v3.x.x ([release notes](https://github.com/chimurai/http-proxy-middleware/releases))
1515

16-
If you're looking for v0.x documentation. Go to:
17-
https://github.com/chimurai/http-proxy-middleware/tree/v0.21.0#readme
16+
See [MIGRATION.md](https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md) for details on how to migrate from v2.x.x to v3.x.x
17+
18+
If you're looking for older documentation. Go to:
19+
20+
- <https://github.com/chimurai/http-proxy-middleware/tree/v2.0.4#readme>
21+
- <https://github.com/chimurai/http-proxy-middleware/tree/v0.21.0#readme>
1822

1923
## TL;DR <!-- omit in toc -->
2024

2125
Proxy `/api` requests to `http://www.example.org`
2226

27+
:bulb: **Tip:** Set the option `changeOrigin` to `true` for [name-based virtual hosted sites](http://en.wikipedia.org/wiki/Virtual_hosting#Name-based).
28+
2329
```javascript
2430
// javascript
2531

@@ -30,8 +36,12 @@ const app = express();
3036

3137
app.use(
3238
'/api',
33-
createProxyMiddleware({ target: 'http://www.example.org/secret', changeOrigin: true })
39+
createProxyMiddleware({
40+
target: 'http://www.example.org/secret',
41+
changeOrigin: true,
42+
})
3443
);
44+
3545
app.listen(3000);
3646

3747
// proxy and change the base path from "/api" to "/secret"
@@ -48,8 +58,12 @@ const app = express();
4858

4959
app.use(
5060
'/api',
51-
createProxyMiddleware({ target: 'http://www.example.org/api', changeOrigin: true })
61+
createProxyMiddleware({
62+
target: 'http://www.example.org/api',
63+
changeOrigin: true,
64+
})
5265
);
66+
5367
app.listen(3000);
5468

5569
// proxy and keep the same base path "/api"
@@ -58,8 +72,6 @@ app.listen(3000);
5872

5973
_All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#options) can be used, along with some extra `http-proxy-middleware` [options](#options).
6074

61-
:bulb: **Tip:** Set the option `changeOrigin` to `true` for [name-based virtual hosted sites](http://en.wikipedia.org/wiki/Virtual_hosting#Name-based).
62-
6375
## Table of Contents <!-- omit in toc -->
6476

6577
<!-- // spell-checker:disable -->
@@ -160,9 +172,9 @@ app.use(
160172

161173
`app.use` documentation:
162174

163-
- express: http://expressjs.com/en/4x/api.html#app.use
164-
- connect: https://github.com/senchalabs/connect#mount-middleware
165-
- polka: https://github.com/lukeed/polka#usebase-fn
175+
- express: <http://expressjs.com/en/4x/api.html#app.use>
176+
- connect: <https://github.com/senchalabs/connect#mount-middleware>
177+
- polka: <https://github.com/lukeed/polka#usebase-fn>
166178

167179
## Options
168180

@@ -302,7 +314,7 @@ const {
302314
loggerPlugin, // log proxy events to a logger (ie. console)
303315
errorResponsePlugin, // return 5xx response on proxy error
304316
proxyEventsPlugin, // implements the "on:" option
305-
} = require('http-proxy-middleware/plugins/default');
317+
} = require('http-proxy-middleware');
306318

307319
createProxyMiddleware({
308320
target: `http://example.org`,
@@ -316,6 +328,10 @@ createProxyMiddleware({
316328

317329
Configure a logger to output information from http-proxy-middleware: ie. `console`, `winston`, `pino`, `bunyan`, `log4js`, etc...
318330

331+
Only `info`, `warn`, `error` are used internally for compatibility across different loggers.
332+
333+
If you use `winston`, make sure to enable interpolation: <https://github.com/winstonjs/winston#string-interpolation>
334+
319335
See also logger recipes ([recipes/logger.md](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/logger.md)) for more details.
320336

321337
```javascript
@@ -424,29 +440,35 @@ The following options are provided by the underlying [http-proxy](https://github
424440
- **option.autoRewrite**: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
425441
- **option.protocolRewrite**: rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.
426442
- **option.cookieDomainRewrite**: rewrites domain of `set-cookie` headers. Possible values:
443+
427444
- `false` (default): disable cookie rewriting
428445
- String: new domain, for example `cookieDomainRewrite: "new.domain"`. To remove the domain, use `cookieDomainRewrite: ""`.
429446
- Object: mapping of domains to new domains, use `"*"` to match all domains.
430447
For example keep one domain unchanged, rewrite one domain and remove other domains:
448+
431449
```json
432450
cookieDomainRewrite: {
433451
"unchanged.domain": "unchanged.domain",
434452
"old.domain": "new.domain",
435453
"*": ""
436454
}
437455
```
456+
438457
- **option.cookiePathRewrite**: rewrites path of `set-cookie` headers. Possible values:
458+
439459
- `false` (default): disable cookie rewriting
440460
- String: new path, for example `cookiePathRewrite: "/newPath/"`. To remove the path, use `cookiePathRewrite: ""`. To set path to root use `cookiePathRewrite: "/"`.
441461
- Object: mapping of paths to new paths, use `"*"` to match all paths.
442462
For example, to keep one path unchanged, rewrite one path and remove other paths:
463+
443464
```json
444465
cookiePathRewrite: {
445466
"/unchanged.path/": "/unchanged.path/",
446467
"/old.path/": "/new.path/",
447468
"*": ""
448469
}
449470
```
471+
450472
- **option.headers**: object, adds [request headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields). (Example: `{host:'www.example.org'}`)
451473
- **option.proxyTimeout**: timeout (in millis) when proxy receives no response from target
452474
- **option.timeout**: timeout (in millis) for incoming requests

cspell.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22
"language": "en",
33
"spellCheckDelayMs": 500,
44
"dictionaries": ["node", "npm", "typescript", "contributors"],
5-
"ignorePaths": ["node_modules/**", "coverage/**", "dist/**", "package.json", "yarn.lock"],
5+
"ignorePaths": [
6+
"node_modules/**",
7+
"coverage/**",
8+
"dist/**",
9+
"package.json",
10+
"yarn.lock",
11+
"*.tgz"
12+
],
613
"dictionaryDefinitions": [
714
{
815
"name": "contributors",
916
"path": "CONTRIBUTORS.txt"
1017
}
1118
],
12-
"ignoreRegExpList": ["[a-z]+path"],
19+
"ignoreRegExpList": ["[a-z]+path", "\\]\\(#[a-z-]+\\)"],
1320
"words": [
1421
"camelcase",
1522
"codesandbox",

examples/connect/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const { createProxyMiddleware } = require('../../dist'); // require('http-proxy-
1111
const jsonPlaceholderProxy = createProxyMiddleware({
1212
target: 'http://jsonplaceholder.typicode.com/users',
1313
changeOrigin: true, // for vhosted sites, changes host header to match to target's host
14-
logLevel: 'debug',
1514
});
1615

1716
const app = connect();

examples/express/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const { createProxyMiddleware } = require('../../dist'); // require('http-proxy-
1010
const jsonPlaceholderProxy = createProxyMiddleware({
1111
target: 'http://jsonplaceholder.typicode.com/users',
1212
changeOrigin: true, // for vhosted sites, changes host header to match to target's host
13-
logLevel: 'debug',
1413
logger: console,
1514
});
1615

recipes/proxy-events.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Proxy Events
22

3-
Subscribe to [`http-proxy`](https://github.com/nodejitsu/node-http-proxy) [![GitHub stars](https://img.shields.io/github/stars/nodejitsu/node-http-proxy.svg?style=social&label=Star)](https://github.com/nodejitsu/node-http-proxy) events: `error`, `proxyReq`, `proxyReqWs`, `proxyRes`, `open`, `close`, `start`, `end`, `econnreset`.
3+
Subscribe to `http-proxy` events: `error`, `proxyReq`, `proxyReqWs`, `proxyRes`, `open`, `close`, `start`, `end`, `econnreset`.
44

55
## on.error
66

recipes/websocket.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ This example will create a proxy middleware with websocket support.
55
```javascript
66
const { createProxyMiddleware } = require('http-proxy-middleware');
77

8-
const socketProxy = createProxyMiddleware('/socket', {
8+
const socketProxy = createProxyMiddleware({
99
target: 'http://localhost:3000',
10+
pathFilter: '/socket',
1011
ws: true,
1112
});
1213
```
@@ -21,12 +22,13 @@ const { createProxyMiddleware } = require('http-proxy-middleware');
2122
const options = {
2223
target: 'http://localhost:3000',
2324
ws: true,
25+
pathFilter: '/socket',
2426
pathRewrite: {
2527
'^/socket': '',
2628
},
2729
};
2830

29-
const socketProxy = createProxyMiddleware('/socket', options);
31+
const socketProxy = createProxyMiddleware(options);
3032
```
3133

3234
## WebSocket - Server update subscription
@@ -38,8 +40,9 @@ Subscribe to server's upgrade event.
3840
```javascript
3941
const { createProxyMiddleware } = require('http-proxy-middleware');
4042

41-
const socketProxy = createProxyMiddleware('/socket', {
43+
const socketProxy = createProxyMiddleware({
4244
target: 'http://localhost:3000',
45+
pathFilter: '/socket',
4346
ws: true,
4447
});
4548

src/get-plugins.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import {
77
} from './plugins/default';
88

99
export function getPlugins(options: Options): Plugin[] {
10+
// don't load default errorResponsePlugin if user has specified their own
11+
const maybeErrorResponsePlugin = !!options.on?.error ? [] : [errorResponsePlugin];
12+
1013
const defaultPlugins: Plugin[] = !!options.ejectPlugins
1114
? [] // no default plugins when ejecting
12-
: [debugProxyErrorsPlugin, proxyEventsPlugin, loggerPlugin, errorResponsePlugin];
15+
: [debugProxyErrorsPlugin, proxyEventsPlugin, loggerPlugin, ...maybeErrorResponsePlugin];
1316
const userPlugins: Plugin[] = options.plugins ?? [];
1417
return [...defaultPlugins, ...userPlugins];
1518
}

0 commit comments

Comments
 (0)