app-backend: remove support for old backend system

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2025-02-27 18:49:01 +01:00
parent d74c59cc8f
commit 32be48c7b4
12 changed files with 71 additions and 152 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-app-backend': minor
---
**BREAKING**: Removed support for the old backend system.
As part of this change the plugin export from `/alpha` as been removed. If you are currently importing `@backstage/plugin-app-backend/alpha`, please update your import to `@backstage/plugin-app-backend`.
-2
View File
@@ -35,7 +35,6 @@
"@backstage/catalog-model": "workspace:^",
"@backstage/config": "workspace:^",
"@backstage/integration": "workspace:^",
"@backstage/plugin-app-backend": "workspace:^",
"@backstage/plugin-auth-backend": "workspace:^",
"@backstage/plugin-auth-node": "workspace:^",
"@backstage/plugin-catalog-backend": "workspace:^",
@@ -67,7 +66,6 @@
"azure-devops-node-api": "^14.0.0",
"better-sqlite3": "^11.0.0",
"dockerode": "^4.0.0",
"example-app": "link:../app",
"express": "^4.17.1",
"express-prom-bundle": "^7.0.0",
"express-promise-router": "^4.1.0",
+1 -4
View File
@@ -44,7 +44,6 @@ import kubernetes from './plugins/kubernetes';
import scaffolder from './plugins/scaffolder';
import search from './plugins/search';
import techdocs from './plugins/techdocs';
import app from './plugins/app';
import permission from './plugins/permission';
import { PluginEnvironment } from './types';
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
@@ -131,7 +130,6 @@ async function main() {
const searchEnv = useHotMemoize(module, () => createEnv('search'));
const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs'));
const kubernetesEnv = useHotMemoize(module, () => createEnv('kubernetes'));
const appEnv = useHotMemoize(module, () => createEnv('app'));
const permissionEnv = useHotMemoize(module, () => createEnv('permission'));
const eventsEnv = useHotMemoize(module, () => createEnv('events'));
@@ -150,8 +148,7 @@ async function main() {
.loadConfig(config)
.addRouter('', await healthcheck(healthcheckEnv))
.addRouter('', metricsHandler())
.addRouter('/api', apiRouter)
.addRouter('', await app(appEnv));
.addRouter('/api', apiRouter);
await service.start().catch(err => {
logger.error(err);
@@ -1,30 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createRouter } from '@backstage/plugin-app-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({
logger: env.logger,
config: env.config,
database: env.database,
appPackageName: 'example-app',
});
}
+1 -1
View File
@@ -23,5 +23,5 @@ backend.add(
data: { app: { packageName: 'example-app' } },
}),
);
backend.add(import('../src/alpha'));
backend.add(import('../src'));
backend.start();
+1 -5
View File
@@ -26,16 +26,12 @@
"license": "Apache-2.0",
"exports": {
".": "./src/index.ts",
"./alpha": "./src/alpha.ts",
"./package.json": "./package.json"
},
"main": "src/index.ts",
"types": "src/index.ts",
"typesVersions": {
"*": {
"alpha": [
"src/alpha.ts"
],
"package.json": [
"package.json"
]
@@ -64,7 +60,6 @@
"@backstage/plugin-app-node": "workspace:^",
"@backstage/plugin-auth-node": "workspace:^",
"@backstage/types": "workspace:^",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"fs-extra": "^11.2.0",
@@ -81,6 +76,7 @@
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/types": "workspace:^",
"@types/express": "^4.17.6",
"@types/supertest": "^2.0.8",
"supertest": "^7.0.0"
},
-13
View File
@@ -1,13 +0,0 @@
## API Report File for "@backstage/plugin-app-backend"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { BackendFeature } from '@backstage/backend-plugin-api';
// @alpha (undocumented)
const _appPlugin: BackendFeature;
export default _appPlugin;
// (No @packageDocumentation comment for this package)
```
-27
View File
@@ -3,36 +3,9 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { AuthService } from '@backstage/backend-plugin-api';
import { BackendFeature } from '@backstage/backend-plugin-api';
import { ConfigSchema } from '@backstage/config-loader';
import { DatabaseService } from '@backstage/backend-plugin-api';
import express from 'express';
import { HttpAuthService } from '@backstage/backend-plugin-api';
import { LoggerService } from '@backstage/backend-plugin-api';
import { RootConfigService } from '@backstage/backend-plugin-api';
// @public
const appPlugin: BackendFeature;
export default appPlugin;
// @public @deprecated (undocumented)
export function createRouter(options: RouterOptions): Promise<express.Router>;
// @public @deprecated (undocumented)
export interface RouterOptions {
appPackageName: string;
// (undocumented)
auth?: AuthService;
// (undocumented)
config: RootConfigService;
database?: DatabaseService;
disableConfigInjection?: boolean;
// (undocumented)
httpAuth?: HttpAuthService;
// (undocumented)
logger: LoggerService;
schema?: ConfigSchema;
staticFallbackHandler?: express.Handler;
}
```
-21
View File
@@ -1,21 +0,0 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { appPlugin } from './service/appPlugin';
/** @alpha */
const _appPlugin = appPlugin;
export default _appPlugin;
+43 -8
View File
@@ -14,14 +14,14 @@
* limitations under the License.
*/
import { AppConfig, ConfigReader } from '@backstage/config';
import { AppConfig } from '@backstage/config';
import express from 'express';
import Router from 'express-promise-router';
import { resolve as resolvePath } from 'path';
import request from 'supertest';
import { createRouter } from './router';
import { loadConfigSchema } from '@backstage/config-loader';
import { mockServices } from '@backstage/backend-test-utils';
import { mockServices, TestDatabases } from '@backstage/backend-test-utils';
jest.mock('../lib/config', () => ({
injectConfig: jest.fn(),
@@ -34,12 +34,24 @@ global.__non_webpack_require__ = {
};
describe('createRouter', () => {
const databases = TestDatabases.create({ ids: ['SQLITE_3'] });
let app: express.Express;
beforeAll(async () => {
const knex = databases.init('SQLITE_3');
const router = await createRouter({
logger: mockServices.logger.mock(),
config: new ConfigReader({}),
database: mockServices.database.mock({
getClient: () => knex,
}),
auth: mockServices.auth(),
httpAuth: mockServices.httpAuth(),
config: mockServices.rootConfig({
data: {
app: { disableStaticFallbackCache: true },
},
}),
appPackageName: 'example-app',
});
app = express().use(router);
@@ -97,7 +109,14 @@ describe('createRouter with static fallback handler', () => {
const router = await createRouter({
logger: mockServices.logger.mock(),
config: new ConfigReader({}),
database: mockServices.database.mock(),
auth: mockServices.auth(),
httpAuth: mockServices.httpAuth(),
config: mockServices.rootConfig({
data: {
app: { disableStaticFallbackCache: true },
},
}),
appPackageName: 'example-app',
staticFallbackHandler,
});
@@ -132,8 +151,16 @@ describe('createRouter config schema test', () => {
it('uses an external schema', async () => {
await createRouter({
logger: mockServices.logger.mock(),
config: new ConfigReader({
test: 'value',
database: mockServices.database.mock(),
auth: mockServices.auth(),
httpAuth: mockServices.httpAuth(),
config: mockServices.rootConfig({
data: {
app: {
disableStaticFallbackCache: true,
},
test: 'value',
},
}),
appPackageName: 'example-app',
schema: await loadConfigSchema({
@@ -173,8 +200,16 @@ describe('createRouter config schema test', () => {
it('uses no external schema', async () => {
await createRouter({
logger: mockServices.logger.mock(),
config: new ConfigReader({
test: 'value',
database: mockServices.database.mock(),
auth: mockServices.auth(),
httpAuth: mockServices.httpAuth(),
config: mockServices.rootConfig({
data: {
app: {
disableStaticFallbackCache: true,
},
test: 'value',
},
}),
appPackageName: 'example-app',
});
+18 -33
View File
@@ -19,7 +19,7 @@ import {
resolvePackagePath,
RootConfigService,
} from '@backstage/backend-plugin-api';
import { AppConfig } from '@backstage/config';
import type { AppConfig } from '@backstage/config';
import helmet from 'helmet';
import express, { Request, Response } from 'express';
import Router from 'express-promise-router';
@@ -35,7 +35,7 @@ import {
CACHE_CONTROL_NO_CACHE,
CACHE_CONTROL_REVALIDATE_CACHE,
} from '../lib/headers';
import { ConfigSchema } from '@backstage/config-loader';
import type { ConfigSchema } from '@backstage/config-loader';
import {
AuthService,
HttpAuthService,
@@ -48,21 +48,20 @@ import { injectConfig, readFrontendConfig } from '../lib/config';
type Mime = { lookup(arg0: string): string };
/**
* @public
* @deprecated Please migrate to the new backend system as this will be removed in the future.
* @internal
*/
export interface RouterOptions {
config: RootConfigService;
logger: LoggerService;
auth?: AuthService;
httpAuth?: HttpAuthService;
auth: AuthService;
httpAuth: HttpAuthService;
/**
* If a database is provided it will be used to cache previously deployed static assets.
*
* This is a built-in alternative to using a `staticFallbackHandler`.
*/
database?: DatabaseService;
database: DatabaseService;
/**
* The name of the app package that content should be served from. The same app package should be
@@ -86,17 +85,6 @@ export interface RouterOptions {
*/
staticFallbackHandler?: express.Handler;
/**
* Disables the configuration injection. This can be useful if you're running in an environment
* with a read-only filesystem, or for some other reason don't want configuration to be injected.
*
* Note that this will cause the configuration used when building the app bundle to be used, unless
* a separate configuration loading strategy is set up.
*
* This also disables configuration injection though `APP_CONFIG_` environment variables.
*/
disableConfigInjection?: boolean;
/**
*
* Provides a ConfigSchema.
@@ -106,8 +94,7 @@ export interface RouterOptions {
}
/**
* @public
* @deprecated Please migrate to the new backend system as this will be removed in the future.
* @internal
*/
export async function createRouter(
options: RouterOptions,
@@ -122,9 +109,9 @@ export async function createRouter(
schema,
} = options;
const disableConfigInjection =
options.disableConfigInjection ??
config.getOptionalBoolean('app.disableConfigInjection');
const disableConfigInjection = config.getOptionalBoolean(
'app.disableConfigInjection',
);
const disableStaticFallbackCache = config.getOptionalBoolean(
'app.disableStaticFallbackCache',
);
@@ -153,13 +140,12 @@ export async function createRouter(
schema,
});
const assetStore =
options.database && !disableStaticFallbackCache
? await StaticAssetsStore.create({
logger,
database: options.database,
})
: undefined;
const assetStore = !disableStaticFallbackCache
? await StaticAssetsStore.create({
logger,
database: options.database,
})
: undefined;
const router = Router();
@@ -167,10 +153,9 @@ export async function createRouter(
const publicDistDir = resolvePath(appDistDir, 'public');
const enablePublicEntryPoint =
(await fs.pathExists(publicDistDir)) && auth && httpAuth;
const enablePublicEntryPoint = await fs.pathExists(publicDistDir);
if (enablePublicEntryPoint && auth && httpAuth) {
if (enablePublicEntryPoint) {
logger.info(
`App is running in protected mode, serving public content from ${publicDistDir}`,
);
-8
View File
@@ -28814,12 +28814,6 @@ __metadata:
languageName: node
linkType: soft
"example-app@link:../app::locator=example-backend-legacy%40workspace%3Apackages%2Fbackend-legacy":
version: 0.0.0-use.local
resolution: "example-app@link:../app::locator=example-backend-legacy%40workspace%3Apackages%2Fbackend-legacy"
languageName: node
linkType: soft
"example-app@workspace:packages/app":
version: 0.0.0-use.local
resolution: "example-app@workspace:packages/app"
@@ -28898,7 +28892,6 @@ __metadata:
"@backstage/cli": "workspace:^"
"@backstage/config": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-app-backend": "workspace:^"
"@backstage/plugin-auth-backend": "workspace:^"
"@backstage/plugin-auth-node": "workspace:^"
"@backstage/plugin-catalog-backend": "workspace:^"
@@ -28934,7 +28927,6 @@ __metadata:
azure-devops-node-api: ^14.0.0
better-sqlite3: ^11.0.0
dockerode: ^4.0.0
example-app: "link:../app"
express: ^4.17.1
express-prom-bundle: ^7.0.0
express-promise-router: ^4.1.0