From e7204e24db829872114524c9fddc8ce08f5ad0d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 9 Dec 2025 08:40:50 +0100 Subject: [PATCH] updated the immediate entity provider example a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- contrib/catalog/ImmediateEntityProvider.ts | 99 ++++++++++++---------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/contrib/catalog/ImmediateEntityProvider.ts b/contrib/catalog/ImmediateEntityProvider.ts index b5580b775a..9f9f986567 100644 --- a/contrib/catalog/ImmediateEntityProvider.ts +++ b/contrib/catalog/ImmediateEntityProvider.ts @@ -1,3 +1,8 @@ +import { + coreServices, + createBackendModule, + LoggerService, +} from '@backstage/backend-plugin-api'; import { ANNOTATION_LOCATION, ANNOTATION_ORIGIN_LOCATION, @@ -10,50 +15,18 @@ import { EntityProvider, EntityProviderConnection, } from '@backstage/plugin-catalog-node'; -import { parseEntityYaml } from '@backstage/plugin-catalog-backend'; +import { parseEntityYaml } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import bodyParser from 'body-parser'; import express from 'express'; import Router from 'express-promise-router'; import lodash from 'lodash'; -import { Logger } from 'winston'; /** * An entity provider attached to a router, that lets users perform direct * manipulation of a set of entities using REST requests. - * - * @remarks - * - * Installation: - * - * Add it to the catalog builder in your - * `packages/backend/src/plugins/catalog.ts`. Note that it BOTH adds a provider - * and amends the catalog router: - * - * ``` - * const immediate = new ImmediateEntityProvider({ - * logger: env.logger, - * handleEntity: (deferred) => { - * // Optionally modify the incoming entity - * }, - * }); - * builder.addEntityProvider(immediate); - * - * // ... - * - * return router.use('/immediate', immediate.getRouter()); - * ``` - * - * API (assume a catalog prefix, e.g. `/api/catalog`): - * - * - `POST /immediate/entities`: Accepts a YAML document of entities, and - * inserts or updates the entities that match that document. Returns 201 OK on - * success. - * - * - `PUT /immediate/entities`: Accepts a YAML document of entities, and - * replaces the entire set of entities managed by the provider with those - * entities. Returns 201 OK on success. */ -export class ImmediateEntityProvider implements EntityProvider { +class ImmediateEntityProvider implements EntityProvider { private connection?: EntityProviderConnection; private readonly entityValidator: (data: unknown) => Entity; @@ -76,7 +49,7 @@ export class ImmediateEntityProvider implements EntityProvider { router.use(bodyParser.raw({ type: '*/*' })); - router.post('/entities', async (req, res) => { + router.post('/immediate/entities', async (req, res) => { if (!this.connection) { throw new Error(`Service is not yet initialized`); } @@ -89,7 +62,7 @@ export class ImmediateEntityProvider implements EntityProvider { res.status(201).end(); }); - router.put('/entities', async (req, res) => { + router.put('/immediate/entities', async (req, res) => { if (!this.connection) { throw new Error(`Service is not yet initialized`); } @@ -151,19 +124,59 @@ export class ImmediateEntityProvider implements EntityProvider { /** * Options for {@link ImmediateEntityProvider}. */ -export interface ImmediateEntityProviderOptions { +interface ImmediateEntityProviderOptions { /** - * The logger to use. + * The logger. */ - logger: Logger; + logger: LoggerService; /** - * An optional function to perform adjustments to, or validate, an incoming - * entity before being stored. It is permitted to modify the deferred entity, - * but the request is static and has had its body consumed. + * An optional callback function to perform adjustments to, or validate, an + * incoming entity before being stored. It is permitted to modify the deferred + * entity, but the request is static and has had its body consumed. */ handleEntity?: ( request: express.Request, deferred: DeferredEntity, ) => void | Promise; } + +/** + * Backend module that installs an immediate entity provider. + * + * @remarks + * + * Install it by doing `backend.add(immediateEntityProviderModule)` in your `packages/backend/src/index.ts` file. + * + * API: + * + * - `POST /api/catalog/immediate/entities`: Accepts a YAML document of entities, and + * inserts or updates the entities that match that document. Returns 201 OK on + * success. + * + * - `PUT /api/catalog/immediate/entities`: Accepts a YAML document of entities, and + * replaces the entire set of entities managed by the provider with those + * entities. Returns 201 OK on success. + */ +export const immediateEntityProviderModule = createBackendModule({ + pluginId: 'catalog', + moduleId: 'immediate-entity-provider', + register(env) { + env.registerInit({ + deps: { + logger: coreServices.logger, + router: coreServices.httpRouter, + catalogProcessing: catalogProcessingExtensionPoint, + }, + async init({ logger, router, catalogProcessing }) { + const provider = new ImmediateEntityProvider({ + logger, + // add handleEntity here if you need to modify incoming entities before they are stored + }); + + catalogProcessing.addEntityProvider(provider); + router.use(provider.getRouter()); + }, + }); + }, +});