news 2026/9/10 4:16:52

Backstage 后端系统命名规范:从插件、模块到扩展点与服务的统一命名模式指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Backstage 后端系统命名规范:从插件、模块到扩展点与服务的统一命名模式指南

Backstage 后端系统命名规范:从插件、模块到扩展点与服务的统一命名模式指南

【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage

本篇技术指南系统讲解 Backstage 后端系统(Backend System)中的命名模式(Naming Patterns)。这些模式统一了跨包的导出命名方式,让开发者仅凭名称即可判断导出物的类型、归属与用途——例如看到xxxPlugin即可确认是后端插件实例,看到xxxExtensionPoint即知是扩展点接口或引用。读完本文,你将掌握插件、模块、扩展点、服务四类核心构件的标准命名格式与 ID 规则,并能在自己的 Backstage 插件与模块开发中直接套用。

命名总原则:camelCase 与 kebab-case 的分工

Backstage 后端系统对命名有一条总体规则:

所有名称(导出标识符)一律使用camelCase;唯一例外是插件与模块的ID,它们使用kebab-case(连字符分隔的小写形式)。

这一规则的目的在于保持各包导出的一致性,降低理解成本。当你在代码库中看到形如catalogModuleGithubEntityProvider的标识符时,可以立即推断出这是一个属于catalog插件的、名为github-entity-provider的模块;而catalogProcessingExtensionPoint则表明它是 catalog 插件的 processing 扩展点引用。

ID 的字符集约束为:仅允许字母、数字与连字符(dash),且必须以字母开头。例如'user-settings''github-entity-provider''catalog.processing'均合法,而'2fa''-foo''foo_bar'这类形式不合规。

下文将按四类核心构件逐一展开,每类都给出格式表、命名示例与仓库中的真实实现佐证。

插件(Plugins):<camelId>Plugin<kebab-id>

命名格式

描述模式示例备注
导出名<camelId>PlugincatalogPluginuserSettingsPlugin
插件 ID'<kebab-id>''catalog''user-settings'仅含字母、数字与连字符,且以字母开头

标准写法

export const userSettingsPlugin = createBackendPlugin({ pluginId: 'user-settings', ... })

后端插件的导出常量以Plugin结尾,插件 ID 使用 kebab-case 并在pluginId字段中声明。

仓库中的真实实现

在 plugins/catalog-backend/src/service/CatalogPlugin.ts 中,catalog 插件正是以catalogPlugin = createBackendPlugin(...)的方式导出;plugins/auth-backend/src/authPlugin.ts 与 plugins/app-backend/src/service/appPlugin.ts 也严格遵循<camelId>Plugin模式。这些常量随后通过包的公共入口统一向外导出,保证了消费方命名体验的一致。

值得留意的是,前端插件的命名遵循相同逻辑。例如 plugins/user-settings/src/plugin.ts 中userSettingsPlugin = createPlugin({ id: 'user-settings', ... }),并在 plugins/user-settings/src/index.ts 中作为userSettingsPlugin导出。这说明<camelId>Plugin+ kebab-case ID 的组合是整个 Backstage(前端与后端)共享的心智模型。

模块(Modules):<pluginId>Module<ModuleId><module-id>

命名格式

描述模式示例备注
导出名<pluginId>Module<ModuleId>catalogModuleGithubEntityProvider
模块 ID'<module-id>''github-entity-provider'仅含字母、数字与连字符,且以字母开头

标准写法

export const catalogModuleGithubEntityProvider = createBackendModule({ pluginId: 'catalog', moduleId: 'github-entity-provider', ... })

模块导出名由「插件 ID 的 camelCase 化 +Module+ 模块自身的 camelCase ID」三段拼接而成。这一命名天然携带了模块归属关系:catalogModuleGithubEntityProvider一眼可知它属于 catalog 插件,服务于 GitHub 实体提供者场景。

仓库中的真实实现

auth 系列模块是这一模式最集中的体现。在 plugins/auth-backend-module-atlassian-provider/src/module.ts 中,模块被命名为authModuleAtlassianProvider = createBackendModule(...);同理还有authModuleAuth0Provider(auth-backend-module-auth0-provider/src/module.ts)、authModuleAwsAlbProvider(auth-backend-module-aws-alb-provider/src/module.ts)等。它们统一遵循<pluginId>Module<ModuleId>规则,全部归属于 auth 插件。

关于createBackendModule的底层契约(如registerExtensionPoint如何将模块与扩展点绑定),可进一步阅读 packages/backend-plugin-api/src/wiring/createBackendModule.ts。

扩展点(Extension Points):Interface 与 Reference 的成对命名

命名格式

描述模式示例
接口(Interface)<PluginId><Name>ExtensionPointCatalogProcessingExtensionPoint
引用(Reference)<pluginId><Name>ExtensionPointcatalogProcessingExtensionPoint
扩展点 ID'<pluginId>.<name>''catalog.processing''foo.barBaz'

扩展点的三个命名要素:接口类型使用 PascalCase(<PluginId><Name>ExtensionPoint),引用常量使用 camelCase(<pluginId><Name>ExtensionPoint),ID使用'<pluginId>.<name>'点分形式。注意 ID 中<name>部分允许 camelCase(如'foo.barBaz'),这是扩展点 ID 与插件/模块 ID 的一个差异点。

标准写法

export interface CatalogProcessingExtensionPoint { ... } export const catalogProcessingExtensionPoint = createExtensionPoint<CatalogProcessingExtensionPoint>({ id: 'catalog.processing', ... })

接口与引用成对出现:接口描述扩展点对外暴露的 API 形状,引用则是模块在注册时用于「指向」该扩展点的令牌。

仓库中的真实实现

catalog 插件完整实现了这一命名:在 plugins/catalog-backend/src/service/CatalogPlugin.ts 中导入了catalogProcessingExtensionPoint,并在插件内部通过extensionPoint: catalogProcessingExtensionPoint完成注册(见同文件 L121)。扩展点的定义来源是@backstage/plugin-catalog-node包,性能测试中也直接引用了该扩展点(见 plugins/catalog-backend/src/tests/performance/getEntitiesPerformance.test.ts)。

createExtensionPoint本身的实现与类型定义可参考 packages/backend-plugin-api/src/wiring/createExtensionPoint.ts,其测试用例 packages/backend-plugin-api/src/wiring/createBackendModule.test.ts 也展示了createExtensionPoint<string>({ id: 'point' })的用法。

服务(Services):Service / ServiceRef / ServiceFactory 的三件套

命名格式

描述模式示例
接口(Interface)<Name>ServiceLoggerServiceDatabaseService
引用(Reference)<name>ServiceRefloggerServiceRefdatabaseServiceRef
服务 ID<pluginId>.<name>'core.rootHttpRouter''catalog.catalogClient'
工厂(Factory)<name>ServiceFactoryloggerServiceFactorydatabaseServiceFactory

服务是后端系统中组件间解耦的核心机制,其命名由四件套构成:接口(<Name>Service)、引用(<name>ServiceRef)、ID(<pluginId>.<name>)与工厂(<name>ServiceFactory)。

标准写法

export interface CatalogClientService { ... } export const catalogClientServiceRef = createServiceRef<CatalogClientService>({ id: 'catalog.catalogClient', ... }) export const catalogClientServiceFactory = createServiceFactory({ service: catalogClientServiceRef, ... })

三者的职责边界:CatalogClientService定义服务能力;catalogClientServiceRef是服务在依赖注入系统中的唯一令牌;catalogClientServiceFactory则负责实例化该服务并在插件启动时按需装配。

核心服务(Core Services)的例外:coreServices 与 mockServices

上述「每个服务引用都导出为独立xxxServiceRef常量」的模式对核心服务存在一个例外:

  • @backstage/backend-plugin-api将所有核心服务的引用统一收纳进单个coreServices集合
  • @backstage/backend-test-utils将所有 mock 服务实现统一收纳进单个mockServices集合

因此在真实代码中,loggerServiceRefdatabaseServiceRef并不存在,取而代之的是coreServices.loggercoreServices.database。文档建议:除非你需要导出的服务数量非常多,否则普通插件应避免逐个导出xxxServiceRef的模式,优先复用coreServices

仓库证据清晰可见:packages/backend-plugin-api/src/services/definitions/coreServices.ts 中export namespace coreServices { ... }收纳了authuserInfocacherootConfig等引用(例如auth = createServiceRef<AuthService>({ id: 'core.auth' })),服务 ID 全部采用'core.<name>'点分形式;packages/backend-test-utils/src/services/mockServices.ts 中同样以export namespace mockServices { ... }形式导出全部 mock 实现,供测试场景直接注入。

此外,@backstage/backend-plugin-api的 alpha 入口 packages/backend-plugin-api/src/alpha/refs.ts 中actionsServiceRefmetricsServiceReftracingServiceRef等仍是逐个导出的形态,可作为「插件自有服务引用」命名方式的参考样例。

Root 前缀:推荐而非强制

对于 root 作用域(scope: 'root')的服务,通常推荐在接口命名上以Root作为前缀,但并非强制要求:

  • 遵循该模式的例子:RootHttpRouterServiceRootLifecycleService
  • 反例:ConfigService同样是 root 作用域服务(在 coreServices.ts 中可见其引用rootConfig = createServiceRef<RootConfigService>({ id: 'core.rootConfig', scope: 'root' })),却没有Root前缀。

从命名一致性的角度,新服务建议优先考虑Root前缀以快速识别生命周期语义;但这不是硬性约束,接口的实际命名可结合服务定位与既有约定权衡。

命名模式速查与实战建议

| 构件 | 导出名 | ID | 示例 | | ---- | ------ | -- | ---- | | 插件 |<camelId>Plugin|'<kebab-id>'|catalogPlugin/'catalog'| | 模块 |<pluginId>Module<ModuleId>|'<module-id>'|catalogModuleGithubEntityProvider/'github-entity-provider'| | 扩展点接口 |<PluginId><Name>ExtensionPoint| — |CatalogProcessingExtensionPoint| | 扩展点引用 |<pluginId><Name>ExtensionPoint|'<pluginId>.<name>'|catalogProcessingExtensionPoint/'catalog.processing'| | 服务接口 |<Name>Service| — |CatalogClientService| | 服务引用 |<name>ServiceRef|'<pluginId>.<name>'|catalogClientServiceRef/'catalog.catalogClient'| | 服务工厂 |<name>ServiceFactory| — |catalogClientServiceFactory|

实战中的三条建议:

  1. 先查命名,再写代码:在创建新插件、模块或扩展点之前,先对照上表确定导出名与 ID,避免后续重构成本。ID 一经发布即成为面向用户的稳定标识,改动会破坏既有配置与依赖关系。
  2. 优先复用核心服务:需要日志、数据库、配置等能力时直接通过coreServices.xxx注入,不要重复导出xxxServiceRef;仅在服务数量庞大或属于插件自有领域时才考虑xxxServiceFactory独立导出。
  3. 让测试保持同构:测试中注入 mock 服务时使用mockServices.xxx集合(见 packages/backend-test-utils/src/services/mockServices.ts),与coreServices的命名一一对应,降低读写测试的心理负担。

延伸阅读

命名模式属于 Backstage 后端系统架构文档体系的一部分,建议按顺序结合阅读:后端系统架构总览、后端(Backends)、服务(Services)、插件(Plugins)、扩展点(Extension Points)、模块(Modules) 与功能加载器(Feature Loaders)。本篇命名规范正是这些架构概念在代码层面的「落地语言」——理解它们,你就能更顺畅地阅读和编写符合 Backstage 社区标准的后端代码。

【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 4:15:39

嵌入式Linux下Modbus RTU开发实战:串口配置与协议实现

在嵌入式Linux上做工业通信&#xff0c;Modbus RTU几乎是一个绕不开的话题。无论是接一个温湿度传感器、采集一路模拟量&#xff0c;还是跟PLC、仪表对上数据&#xff0c;这套基于RS485的串口协议凭借简单、稳定、生态成熟&#xff0c;依然是现场设备接入的首选方式之一。 这篇…

作者头像 李华
网站建设 2026/9/10 4:15:09

嵌入式AI生成代码验证体系:从静态分析到实车路试的完整实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 4:12:07

CANN/GE更新图特征内存基址API

UpdateGraphFeatureMemoryBase 【免费下载链接】ge GE&#xff08;Graph Engine&#xff09;是面向昇腾的图编译器和执行器&#xff0c;提供了计算图优化、多流并行、内存复用和模型下沉等技术手段&#xff0c;加速模型执行效率&#xff0c;减少模型内存占用。 GE 提供对 PyTor…

作者头像 李华