Skip to content

Commit

Permalink
feat: remove shorthand usage [BREAKING CHANGE] (#716)
Browse files Browse the repository at this point in the history
  • Loading branch information
chimurai authored Feb 19, 2022
1 parent 2d6741a commit 1540dac
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 280 deletions.
63 changes: 16 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,12 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
- [Install](#install)
- [Core concept](#core-concept)
- [Example](#example)
- [app.use(path, proxy)](#appusepath-proxy)
- [Context matching](#context-matching)
- [Options](#options)
- [http-proxy-middleware options](#http-proxy-middleware-options)
- [http-proxy events](#http-proxy-events)
- [http-proxy options](#http-proxy-options)
- [Shorthand](#shorthand)
- [app.use(path, proxy)](#appusepath-proxy)
- [WebSocket](#websocket)
- [External WebSocket upgrade](#external-websocket-upgrade)
- [Intercept and manipulate requests](#intercept-and-manipulate-requests)
Expand Down Expand Up @@ -104,15 +103,6 @@ const apiProxy = createProxyMiddleware('/api', { target: 'http://www.example.org

(full list of [`http-proxy-middleware` configuration options](#options))

#### createProxyMiddleware(uri [, config])

```javascript
// shorthand syntax for the example above:
const apiProxy = createProxyMiddleware('http://www.example.org/api');
```

More about the [shorthand configuration](#shorthand).

## Example

An example with `express` server.
Expand Down Expand Up @@ -148,6 +138,21 @@ app.use('/api', exampleProxy);
app.listen(3000);
```

### app.use(path, proxy)

If you want to use the server's `app.use` `path` parameter to match requests;
Create and mount the proxy without the http-proxy-middleware `context` parameter:

```javascript
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
```

`app.use` documentation:

- express: http://expressjs.com/en/4x/api.html#app.use
- connect: https://github.com/senchalabs/connect#mount-middleware
- polka: https://github.com/lukeed/polka#usebase-fn

## Context matching

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.
Expand Down Expand Up @@ -422,47 +427,11 @@ The following options are provided by the underlying [http-proxy](https://github
};
```
## Shorthand
Use the shorthand syntax when verbose configuration is not needed. The `context` and `option.target` will be automatically configured when shorthand is used. Options can still be used if needed.
```javascript
createProxyMiddleware('http://www.example.org:8000/api');
// createProxyMiddleware('/api', {target: 'http://www.example.org:8000'});

createProxyMiddleware('http://www.example.org:8000/api/books/*/**.json');
// createProxyMiddleware('/api/books/*/**.json', {target: 'http://www.example.org:8000'});

createProxyMiddleware('http://www.example.org:8000/api', { changeOrigin: true });
// createProxyMiddleware('/api', {target: 'http://www.example.org:8000', changeOrigin: true});
```
### app.use(path, proxy)
If you want to use the server's `app.use` `path` parameter to match requests;
Create and mount the proxy without the http-proxy-middleware `context` parameter:
```javascript
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
```
`app.use` documentation:
- express: http://expressjs.com/en/4x/api.html#app.use
- connect: https://github.com/senchalabs/connect#mount-middleware
- polka: https://github.com/lukeed/polka#usebase-fn
## WebSocket
```javascript
// verbose api
createProxyMiddleware('/', { target: 'http://echo.websocket.org', ws: true });

// shorthand
createProxyMiddleware('http://echo.websocket.org', { ws: true });

// shorter shorthand
createProxyMiddleware('ws://echo.websocket.org');
```
### External WebSocket upgrade
Expand Down
62 changes: 0 additions & 62 deletions recipes/shorthand.md

This file was deleted.

29 changes: 0 additions & 29 deletions src/config-factory.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import isPlainObj = require('is-plain-obj');
import * as url from 'url';
import { ERRORS } from './errors';
import { getInstance } from './logger';
import { Filter, Options } from './types';
Expand All @@ -22,17 +21,6 @@ export function createConfig(context, opts?: Options): Config {

// app.use('/api', proxy('http://localhost:9000'));
// app.use(proxy('http://localhost:9000/api'));
} else if (isStringShortHand(context)) {
const oUrl = url.parse(context);
const target = [oUrl.protocol, '//', oUrl.host].join('');

config.context = oUrl.pathname || '/';
config.options = Object.assign(config.options, { target }, opts);

if (oUrl.protocol === 'ws:' || oUrl.protocol === 'wss:') {
config.options.ws = true;
}
// app.use('/api', proxy({target:'http://localhost:9000'}));
} else {
config.context = context;
config.options = Object.assign(config.options, opts);
Expand All @@ -47,23 +35,6 @@ export function createConfig(context, opts?: Options): Config {
return config;
}

/**
* Checks if a String only target/config is provided.
* This can be just the host or with the optional path.
*
* @example
* app.use('/api', proxy('http://localhost:9000'));
* app.use(proxy('http://localhost:9000/api'));
*
* @param {String} context [description]
* @return {Boolean} [description]
*/
function isStringShortHand(context: Filter) {
if (typeof context === 'string') {
return !!url.parse(context).host;
}
}

/**
* Checks if a Object only config is provided, without a context.
* In this case the all paths will be proxied.
Expand Down
14 changes: 0 additions & 14 deletions test/e2e/http-proxy-middleware.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,20 +389,6 @@ describe('E2E http-proxy-middleware', () => {
});
});

describe('shorthand usage', () => {
beforeEach(() => {
agent = request(
createApp(createProxyMiddleware(`http://localhost:${mockTargetServer.port}/api`))
);
});

it('should have proxy with shorthand configuration', async () => {
await mockTargetServer.get('/api/foo/bar').thenReply(200, 'HELLO /api/foo/bar');
const response = await agent.get(`/api/foo/bar`).expect(200);
expect(response.text).toBe('HELLO /api/foo/bar');
});
});

describe('express with path + proxy', () => {
beforeEach(() => {
agent = request(
Expand Down
26 changes: 0 additions & 26 deletions test/e2e/websocket.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,32 +95,6 @@ describe('E2E WebSocket proxy', () => {
});
});

describe('option.ws with external server "upgrade" and shorthand usage', () => {
beforeEach(() => {
proxyServer = createApp(
createProxyMiddleware(`ws://localhost:${WS_SERVER_PORT}`, {
pathRewrite: { '^/socket': '' },
})
).listen(SERVER_PORT);

proxyServer.on('upgrade', proxyMiddleware.upgrade);
});

beforeEach((done) => {
ws = new WebSocket(`ws://localhost:${SERVER_PORT}/socket`);
ws.on('open', done);
});

it('should proxy to path', (done) => {
ws.on('message', (data, isBinary) => {
const message = isBinary ? data : data.toString();
expect(message).toBe('foobar');
done();
});
ws.send('foobar');
});
});

describe('with router and pathRewrite', () => {
beforeEach(() => {
// override
Expand Down
103 changes: 1 addition & 102 deletions test/unit/config-factory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,92 +26,7 @@ describe('configFactory', () => {
});
});

describe('shorthand String', () => {
describe('shorthand String config', () => {
beforeEach(() => {
result = createConfig('http://www.example.org:8000/api');
});

it('should return config object', () => {
expect(Object.keys(result)).toEqual(['context', 'options']);
});

it('should return config object with context', () => {
expect(result.context).toBe('/api');
});

it('should return config object with options', () => {
expect(result.options).toEqual({
target: 'http://www.example.org:8000',
});
});
});

describe('shorthand String config for whole domain', () => {
beforeEach(() => {
result = createConfig('http://www.example.org:8000');
});

it('should return config object with context', () => {
expect(result.context).toBe('/');
});
});

describe('shorthand String config for websocket url', () => {
beforeEach(() => {
result = createConfig('ws://www.example.org:8000');
});

it('should return config object with context', () => {
expect(result.context).toBe('/');
});

it('should return options with ws = true', () => {
expect(result.options.ws).toBe(true);
});
});

describe('shorthand String config for secure websocket url', () => {
beforeEach(() => {
result = createConfig('wss://www.example.org:8000');
});

it('should return config object with context', () => {
expect(result.context).toBe('/');
});

it('should return options with ws = true', () => {
expect(result.options.ws).toBe(true);
});
});

describe('shorthand String config with globbing', () => {
beforeEach(() => {
result = createConfig('http://www.example.org:8000/api/*.json');
});

it('should return config object with context', () => {
expect(result.context).toBe('/api/*.json');
});
});

describe('shorthand String config with options', () => {
beforeEach(() => {
result = createConfig('http://www.example.org:8000/api', {
changeOrigin: true,
});
});

it('should return config object with additional options', () => {
expect(result.options).toEqual({
changeOrigin: true,
target: 'http://www.example.org:8000',
});
});
});
});

describe('shorthand Object config', () => {
describe('Object config', () => {
beforeEach(() => {
result = createConfig({ target: 'http://www.example.org:8000' });
});
Expand Down Expand Up @@ -156,21 +71,5 @@ describe('configFactory', () => {
expect(fn).not.toThrowError(Error);
});
});

describe('faulty config. mixing classic with shorthand', () => {
beforeEach(() => {
result = createConfig('http://localhost:3000/api', {
target: 'http://localhost:8000',
});
});

it('should use the target in the configuration as target', () => {
expect(result.options.target).toBe('http://localhost:8000');
});

it('should not use the host from the shorthand as target', () => {
expect(result.options.target).not.toBe('http://localhost:3000');
});
});
});
});

0 comments on commit 1540dac

Please sign in to comment.