Skip to main content

后端插件

本页介绍了在 Backstage 资源库中创建和管理后端插件的过程。

创建后端插件

在 Backstage 版本库根目录下发出以下命令,即可创建一个新的、基本的后端插件包:

yarn new --select backend-plugin

另请参见--help标志为new命令中的其他选项,尤其是--scope--no-private标记,用于控制新创建软件包的命名和发布。 您的 repo 根目录中的package.json也可能已经为它们设置了一些默认值。

您将被要求为插件提供一个名称。 这是一个标识符,将成为 NPM 软件包名称的一部分,因此请将其写得简短,只包含用破折号分隔的小写字母,例如carmenNPM 软件包的完整名称如下@internal/plugin-carmen-backend取决于传递给new命令,以及您对new命令package.json.

创建插件需要一点时间,请耐心等待。 它将帮助运行初始安装和构建命令,这样你的软件包就可以被黑客入侵了!它将位于你的plugins目录,例如plugins/carmen-backend.

出于简单的开发目的,后端插件实际上可以以独立模式启动。 您可以对服务进行初步测试:

cd plugins/carmen-backend
LEGACY_BACKEND_START=true yarn start

注意:当我们完全过渡到 新后端系统时,需要使用 LEGACY_BACKEND_START=true 。模板尚未迁移;您可以在 issue 21288 中对此进行跟踪。

它会思考一下,然后说Listening on :7007在另一个终端窗口中,运行

curl localhost:7007/carmen/health

返回值应为{"status":"ok"}成功!新闻Ctrl + c以再次阻止它。

开发后端插件

一个新创建的后端插件在整个应用程序中基本上什么也不做。 它有一小套基本的依赖关系,并在以下文件中公开了一个 Express 路由器src/service/router.ts在这里,您将开始添加路由,并将这些路由连接到实际的底层功能。 但您的 Backstage 应用程序/后端中没有任何东西会公开这些路由。

要实际连接并运行插件路由器,您需要对后端进行一些修改。

# From your Backstage root directory
yarn add --cwd packages/backend @internal/plugin-carmen-backend@^0.1.0 # Change this to match the plugin's package.json

创建一个名为packages/backend/src/plugins/carmen.ts并添加以下内容

import { createRouter } from '@internal/plugin-carmen-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';

export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
// Here is where you will add all of the required initialization code that
// your backend plugin needs to be able to start!

// The env contains a lot of goodies, but our router currently only
// needs a logger
return await createRouter({
logger: env.logger,
});
}

最后,将其接入整个后端路由器。 编辑packages/backend/src/index.ts:

import carmen from './plugins/carmen';
// ..
async function main() {
// ..
const carmenEnv = useHotMemoize(module, () => createEnv('carmen'));
apiRouter.use('/carmen', await carmen(carmenEnv));

启动后端(例如使用yarn start-backend从 repo 根目录),你应该可以从中获取数据。

# Note the extra /api here
curl localhost:7007/api/carmen/health

返回值应为{"status":"ok"}像以前一样成功

利用数据库

Backstage 后端内置了 SQL 数据库访问功能。 大多数有持久性需求的插件都会选择使用该功能,以便 Backstage 操作员可以统一管理数据库需求。

的环境对象的一部分。createPlugin函数,有一个database字段。克耐克斯连接对象。

// in packages/backend/src/plugins/carmen.ts
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const db: Knex<any, unknown[]> = await env.database.getClient();

// You will then pass this client into your actual plugin implementation
// code, maybe similar to the following:
const model = new CarmenDatabaseModel(db);
return await createRouter({
model: model,
logger: env.logger,
});
}

您可能会注意到getClient调用没有参数,这是因为所有插件数据库需求都在backend.database配置键的app-config.yaml框架甚至可以在幕后确保,如果逻辑数据库不存在,就会根据Backstage操作员决定的规则自动创建。

主软件仓库中的内置插件也选择使用 Knex 库来管理模式迁移,但你也可以根据自己的需要进行迁移。

参见Knex 库文档了解如何编写模式迁移和对数据库执行 SQL 查询的示例和详情。

利用用户身份

Backstage 后端具有检索登录用户身份的功能。

的环境对象的一部分。createPlugin函数,有一个identity你可以用它从请求中获取身份信息。

// in packages/backend/src/plugins/carmen.ts
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({
model: model,
logger: env.logger,
identity: env.identity,
});
}

然后,插件就可以从请求中提取身份信息。

export async function createRouter(
options: RouterOptions,
): Promise<express.Router> {
const router = Router();
const { identity } = options;

router.post('/example', async (req, res) => {
const userIdentity = await identity.getIdentity({ request: req });
..
});