From fbecb2ebda6707e8d4647536eba8ae010f38aa17 Mon Sep 17 00:00:00 2001 From: Alec Jacobs Date: Tue, 16 Apr 2024 16:10:29 -0700 Subject: [PATCH 1/4] feat(backend-app-api): add ability to configure node server in root http router Signed-off-by: Alec Jacobs --- packages/backend-app-api/api-report.md | 5 +++ .../rootHttpRouterServiceFactory.ts | 44 +++++++++++-------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index 63f43eff2e..5720c1c60f 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -37,6 +37,7 @@ import { RootHttpRouterService } from '@backstage/backend-plugin-api'; import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; +import type { Server } from 'node:http'; import { ServiceFactory } from '@backstage/backend-plugin-api'; import { ServiceFactoryOrFunction } from '@backstage/backend-plugin-api'; import { TokenManagerService } from '@backstage/backend-plugin-api'; @@ -287,6 +288,8 @@ export interface RootHttpRouterConfigureContext { // (undocumented) app: Express_2; // (undocumented) + applyDefaults: () => void; + // (undocumented) config: RootConfigService; // (undocumented) lifecycle: LifecycleService; @@ -296,6 +299,8 @@ export interface RootHttpRouterConfigureContext { middleware: MiddlewareFactory; // (undocumented) routes: RequestHandler; + // (undocumented) + server: Server; } // @public (undocumented) diff --git a/packages/backend-app-api/src/services/implementations/rootHttpRouter/rootHttpRouterServiceFactory.ts b/packages/backend-app-api/src/services/implementations/rootHttpRouter/rootHttpRouterServiceFactory.ts index 4c410e25ea..a469a2f303 100644 --- a/packages/backend-app-api/src/services/implementations/rootHttpRouter/rootHttpRouterServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/rootHttpRouter/rootHttpRouterServiceFactory.ts @@ -22,6 +22,7 @@ import { LoggerService, } from '@backstage/backend-plugin-api'; import express, { RequestHandler, Express } from 'express'; +import type { Server } from 'node:http'; import { createHttpServer, MiddlewareFactory, @@ -34,11 +35,13 @@ import { DefaultRootHttpRouter } from './DefaultRootHttpRouter'; */ export interface RootHttpRouterConfigureContext { app: Express; + server: Server; middleware: MiddlewareFactory; routes: RequestHandler; config: RootConfigService; logger: LoggerService; lifecycle: LifecycleService; + applyDefaults: () => void; } /** @@ -54,15 +57,8 @@ export type RootHttpRouterFactoryOptions = { configure?(context: RootHttpRouterConfigureContext): void; }; -function defaultConfigure(context: RootHttpRouterConfigureContext) { - const { app, routes, middleware } = context; - app.use(middleware.helmet()); - app.use(middleware.cors()); - app.use(middleware.compression()); - app.use(middleware.logging()); - app.use(routes); - app.use(middleware.notFound()); - app.use(middleware.error()); +function defaultConfigure({ applyDefaults }: RootHttpRouterConfigureContext) { + applyDefaults(); } /** @public */ @@ -81,22 +77,32 @@ export const rootHttpRouterServiceFactory = createServiceFactory( const router = DefaultRootHttpRouter.create({ indexPath }); const middleware = MiddlewareFactory.create({ config, logger }); - - configure({ - app, - routes: router.handler(), - middleware, - config, - logger, - lifecycle, - }); - + const routes = router.handler(); const server = await createHttpServer( app, readHttpServerOptions(config.getOptionalConfig('backend')), { logger }, ); + configure({ + app, + server, + routes, + middleware, + config, + logger, + lifecycle, + applyDefaults() { + app.use(middleware.helmet()); + app.use(middleware.cors()); + app.use(middleware.compression()); + app.use(middleware.logging()); + app.use(routes); + app.use(middleware.notFound()); + app.use(middleware.error()); + }, + }); + lifecycle.addShutdownHook(() => server.stop()); await server.start(); From 85106586796938ef2e7d660616ae3db9f229d933 Mon Sep 17 00:00:00 2001 From: Alec Jacobs Date: Tue, 16 Apr 2024 16:20:45 -0700 Subject: [PATCH 2/4] docs(root-http-router): update docs for server configuration Signed-off-by: Alec Jacobs --- .../core-services/root-http-router.md | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/backend-system/core-services/root-http-router.md b/docs/backend-system/core-services/root-http-router.md index 97666cae9d..b3522e1752 100644 --- a/docs/backend-system/core-services/root-http-router.md +++ b/docs/backend-system/core-services/root-http-router.md @@ -5,7 +5,7 @@ sidebar_label: Root Http Router description: Documentation for the Root Http Router service --- -The root HTTP router is a service that allows you to register routes on the root of the backend service. This is useful for things like health checks, or other routes that you want to expose on the root of the backend service. It is used as the base router that backs the `httpRouter` service. Most likely you won't need to use this service directly, but rather use the `httpRouter` service. +The root HTTP router is a service that allows you to register routes on the root of the backend service. This is useful for things like health checks, or other routes that you want to expose on the root of the backend service. It is used as the base router that backs the `httpRouter` service and starts the Node.js HTTP server on backend startup. Most likely you won't need to use this service directly, but rather use the `httpRouter` service. The `/api/:pluginId/` path prefix is reserved for use by plugins to register their own routes via the [HttpRouter](./http-router.md) service. @@ -78,3 +78,26 @@ backend.add( ``` Note that requests towards `/api/*` will never be handled by the `routes` handler unless a matching plugin exists, and will instead typically falling through to the `middleware.notFound()` handler. That is the case regardless of whether there is a configured `indexPath` or not. + +The root HTTP Router service also allows for configuration of the underlying Node.js HTTP server object. This is useful for modifying settings on the HTTP server itself, such as server [timeout](https://nodejs.org/api/http.html#servertimeout), [keepAliveTimeout](https://nodejs.org/api/http.html#serverkeepalivetimeout), and [headersTimeout](https://nodejs.org/api/http.html#serverheaderstimeout). + +A `applyDefaults` helper is also made available to use the default app/router configuration while still enabling custom server configuration + +```ts +import { rootHttpRouterServiceFactory } from '@backstage/backend-app-api'; + +const backend = createBackend(); + +backend.add( + rootHttpRouterServiceFactory({ + configure: ({ server, applyDefaults }) => { + // apply default app/router configuration + applyDefaults(); + + // customize the Node.js HTTP Server timeouts + server.keepAliveTimeout = 65 * 1000; + server.headersTimeout = 66 * 1000; + }, + }), +); +``` From 4cd5ff038c5945fecd33f93bb93d22cb57056bd0 Mon Sep 17 00:00:00 2001 From: Alec Jacobs Date: Tue, 16 Apr 2024 16:24:03 -0700 Subject: [PATCH 3/4] chore: generate changeset Signed-off-by: Alec Jacobs --- .changeset/cuddly-chairs-kick.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cuddly-chairs-kick.md diff --git a/.changeset/cuddly-chairs-kick.md b/.changeset/cuddly-chairs-kick.md new file mode 100644 index 0000000000..acd7b83b0c --- /dev/null +++ b/.changeset/cuddly-chairs-kick.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': minor +--- + +Add ability to configure the Node.js HTTP Server when configuring the root HTTP Router service From 5becaa1e672da08ff2df411f9936728729d86688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 22 Apr 2024 11:20:56 +0200 Subject: [PATCH 4/4] Update .changeset/cuddly-chairs-kick.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/cuddly-chairs-kick.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/cuddly-chairs-kick.md b/.changeset/cuddly-chairs-kick.md index acd7b83b0c..ebb53b8e26 100644 --- a/.changeset/cuddly-chairs-kick.md +++ b/.changeset/cuddly-chairs-kick.md @@ -1,5 +1,5 @@ --- -'@backstage/backend-app-api': minor +'@backstage/backend-app-api': patch --- Add ability to configure the Node.js HTTP Server when configuring the root HTTP Router service