Merge pull request #2132 from spotify/freben/proxy-config
feat(proxy-backend): more proxy config tweaks and docs
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Proxy backend plugin
|
||||
|
||||
This is the backend plugin that enables proxy definitions to be declared in and read from app-config.yaml.
|
||||
This is the backend plugin that enables proxy definitions to be declared in,
|
||||
and read from, `app-config.yaml`.
|
||||
|
||||
Relies on the `http-proxy-middleware` package.
|
||||
|
||||
@@ -10,27 +11,22 @@ This backend plugin can be started in a standalone mode from directly in this pa
|
||||
with `yarn start`. However, it will have limited functionality and that process is
|
||||
most convenient when developing the plugin itself.
|
||||
|
||||
To run it within the backend do:
|
||||
|
||||
1. Register the router in `packages/backend/src/index.ts`:
|
||||
|
||||
```ts
|
||||
const proxyEnv = useHotMemoize(module, () => createEnv('proxy'));
|
||||
|
||||
const service = createServiceBuilder(module)
|
||||
.loadConfig(configReader)
|
||||
/** several different routers */
|
||||
.addRouter('/', await proxy(proxyEnv));
|
||||
```
|
||||
|
||||
2. Start the backend
|
||||
The proxy is already installed in the Backstage backend per default, so you can also
|
||||
start up the full example backend to experiment with the proxy.
|
||||
|
||||
```bash
|
||||
yarn workspace example-backend start
|
||||
```
|
||||
|
||||
This will launch the full example backend.
|
||||
## Configuration
|
||||
|
||||
See [the proxy docs](https://backstage.io/docs/plugins/proxying).
|
||||
|
||||
## Links
|
||||
|
||||
- [Call Existing API](https://backstage.io/docs/plugins/call-existing-api) helps the
|
||||
decision process of what method of communication to use from a frontend plugin to
|
||||
your API
|
||||
- [The proxy plugin documentation](https://backstage.io/docs/plugins/proxying) describes
|
||||
configuration options and more
|
||||
- [http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware)
|
||||
|
||||
@@ -26,6 +26,7 @@ describe('createRouter', () => {
|
||||
const router = await createRouter({
|
||||
config,
|
||||
logger,
|
||||
pathPrefix: '/proxy',
|
||||
});
|
||||
expect(router).toBeDefined();
|
||||
});
|
||||
|
||||
@@ -17,21 +17,57 @@
|
||||
import { Config } from '@backstage/config';
|
||||
import express from 'express';
|
||||
import Router from 'express-promise-router';
|
||||
import createProxyMiddleware from 'http-proxy-middleware';
|
||||
import createProxyMiddleware, {
|
||||
Config as ProxyConfig,
|
||||
Proxy,
|
||||
} from 'http-proxy-middleware';
|
||||
import { Logger } from 'winston';
|
||||
|
||||
export interface RouterOptions {
|
||||
logger: Logger;
|
||||
config: Config;
|
||||
// The URL path prefix that the router itself is mounted as, commonly "/proxy"
|
||||
pathPrefix: string;
|
||||
}
|
||||
|
||||
// Creates a proxy middleware, possibly with defaults added on top of the
|
||||
// given config.
|
||||
function buildMiddleware(
|
||||
pathPrefix: string,
|
||||
route: string,
|
||||
config: string | ProxyConfig,
|
||||
): Proxy {
|
||||
const fullConfig =
|
||||
typeof config === 'string' ? { target: config } : { ...config };
|
||||
|
||||
// Default is to do a path rewrite that strips out the proxy's path prefix
|
||||
// and the rest of the route.
|
||||
if (fullConfig.pathRewrite === undefined) {
|
||||
const routeWithSlash = route.endsWith('/') ? route : `${route}/`;
|
||||
fullConfig.pathRewrite = {
|
||||
[`^${pathPrefix}${routeWithSlash}`]: '/',
|
||||
};
|
||||
}
|
||||
|
||||
// Default is to update the Host header to the target
|
||||
if (fullConfig.changeOrigin === undefined) {
|
||||
fullConfig.changeOrigin = true;
|
||||
}
|
||||
|
||||
return createProxyMiddleware(fullConfig);
|
||||
}
|
||||
|
||||
export async function createRouter(
|
||||
options: RouterOptions,
|
||||
): Promise<express.Router> {
|
||||
const router = Router();
|
||||
const proxyConfig = options.config.get('proxy') ?? {};
|
||||
|
||||
const proxyConfig = options.config.getOptional('proxy') ?? {};
|
||||
Object.entries(proxyConfig).forEach(([route, proxyRouteConfig]) => {
|
||||
router.use(route, createProxyMiddleware(proxyRouteConfig));
|
||||
router.use(
|
||||
route,
|
||||
buildMiddleware(options.pathPrefix, route, proxyRouteConfig),
|
||||
);
|
||||
});
|
||||
|
||||
return router;
|
||||
|
||||
@@ -40,6 +40,7 @@ export async function startStandaloneServer(
|
||||
const router = await createRouter({
|
||||
config,
|
||||
logger,
|
||||
pathPrefix: '/proxy',
|
||||
});
|
||||
const service = createServiceBuilder(module)
|
||||
.enableCors({ origin: 'http://localhost:3000' })
|
||||
|
||||
Reference in New Issue
Block a user