当前位置: 首页 > news >正文

[Backstage] 软件模板Scaffolder | 定义“Node.js微服务“

第6章:软件模板(Scaffolder)

在上一章后端插件中,我们探讨了服务器端组件如何扩展Backstage的能力,处理复杂逻辑和与外部系统的集成

这些后端功能许多用于自动化常规开发任务,其中最强大的例子之一就是软件模板

想象公司正在快速发展,新团队不断创建新的软件组件——微服务、网站、库、数据管道等。每当新项目启动时,开发者都会面临类似的问题:

  • “在这里设置新的Node.js服务的’正确’方式是什么?”
  • “我应该使用哪种文件夹结构?”
  • “如何配置我们的标准CI/CD流水线?”
  • “我应该把catalog-info.yaml文件放在哪里以注册到软件目录?”
  • “默认应该包含哪些依赖?”

这通常导致开发者复制旧项目,遗漏关键配置,或最终导致整个组织内的设置不一致。这种"重复造轮子"浪费了时间,引入错误,并使得长期维护项目更加困难。

Backstage中的软件模板功能(通常称为Scaffolder)解决了这个问题

它就像开发者门户中的主厨,只需你提供少量"食材",就能快速制作出完美标准化的新项目。它提供创建新软件组件的"配方",确保一致性、最佳实践和开发者的快速启动。

软件模板解决了什么问题?

软件模板简化了创建新软件的过程。它们提供了一种引导式、自动化的方式来启动项目,而非手动设置或复制粘贴。它们帮助我们:

  • 标准化项目:确保所有新项目遵循组织的最佳实践、技术栈和结构。
  • 加速开发:开发者可以在几分钟内启动新项目,预先配置好所需的一切,让他们专注于编写功能代码,而非样板代码。
  • 减少错误:自动化重复的设置任务,最小化人为错误,确保关键配置(如安全设置或合规性)始终包含。
  • 即时集成:自动将新组件注册到软件目录,通过TechDocs链接到文档,并从一开始就设置好CI/CD流水线。

让我们考虑一个实际用例:新开发者"Sam"需要为公司创建一个全新的"邮件通知服务"。它需要是一个标准的Node.js微服务,遵循公司关于文件夹结构的最佳实践,包含基本的CI/CD流水线,并自动注册到软件目录。软件模板如何帮助Sam快速且正确地实现这一点?

软件模板的核心概念

软件模板由几个核心思想定义:

  1. 模板(配方卡片):本质上,模板是描述如何创建新软件组件的YAML文件。它们包含:

    • 元数据:关于模板本身的基本信息(名称、描述、所有者)。
    • 参数:定义用户需要提供的信息(如项目名称、所有者、仓库URL)。Backstage用此生成用户友好的表单。
    • 步骤/动作:Scaffolder后端将执行的任务序列。可能包括获取代码、修改代码、创建仓库或注册实体。
  2. Scaffolder(自动化主厨):这是Backstage中的后端插件,负责获取模板、收集用户输入并执行所有定义的步骤。它协调新软件组件的创建。

  3. 动作(烹饪步骤):这些是Scaffolder可以执行的独立、预定义操作。可以将其视为单独的烹饪指令。例如:

    • fetch:template:下载代码"骨架"(基本项目结构)并应用模板。
    • publish:github:创建新的GitHub仓库并将模板化代码推送到其中。
    • catalog:register:将新创建的组件作为实体注册到软件目录。
      Backstage提供了许多内置动作,甚至可以编写自定义动作。
  4. 模板引擎(智能搅拌器):在fetch:template下载的代码"骨架"中,有特殊的占位符(如${{ values.name }})。Backstage使用模板引擎(如Nunjucks)将这些占位符替换为用户在表单中提供的值,为新项目定制代码。

解决用例:创建"邮件通知服务"

让我们看看Sam如何使用软件模板快速正确地创建"邮件通知服务":

  1. 导航到"创建":Sam打开Backstage门户,点击主导航中的"创建"标签。这里列出了所有可用的软件模板。
  2. 选择模板:Sam选择"Node.js微服务"模板,该模板用于标准化新的后端服务。
  3. 填写表单:出现一个表单,直接由模板的parameters部分生成。Sam提供必要的细节:
    • 项目名称email-notification-service
    • 所有者notifications-team(使用OwnerPicker字段从软件目录拉取)
    • 仓库位置github.com/my-org/email-notification-service(使用RepoUrlPicker字段)
  4. 审查并创建:Sam审查输入并点击"创建"。
  5. Scaffolder接管:Backstage Scaffolder(一个后端插件)开始执行模板定义的steps
  6. 成功:片刻之后,过程完成。Sam看到新GitHub仓库和新注册的软件目录实体的链接

"Node.js微服务"模板如何定义?

让我们看一个简化版的template.yaml文件示例。该文件通常位于Backstage监控的Git仓库中。

# 告诉Backstage这是一个模板及其版本
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:name: nodejs-microservice-templatetitle: Node.js微服务description: 带有基本CI/CD的标准Node.js微服务,准备部署。
spec:owner: default/platform-team # 谁维护此模板type: service # 创建什么类型的软件# 定义用户在Backstage UI中看到的输入字段parameters:- title: 提供基本信息required: ['name', 'owner']properties:name:title: 项目名称type: stringdescription: 新服务的唯一标识符(如email-notification-service)ui:autofocus: trueowner:title: 所有者type: stringdescription: 拥有此服务的团队或用户。ui:field: OwnerPicker # 从目录实体中选择的特殊UI字段ui:options:catalogFilter:kind: Group # 仅显示组作为所有者- title: 选择仓库位置required: ['repoUrl']properties:repoUrl:title: 仓库位置type: stringui:field: RepoUrlPicker # 另一个用于Git仓库的特殊UI字段ui:options:allowedHosts:- github.com # 仅允许GitHub仓库# Scaffolder后端将执行的动作steps:- id: fetch-skeletonname: 获取基础代码骨架action: fetch:template # 获取代码模板的内置动作input:url: ./skeleton # 指向模板仓库中名为'skeleton'的子文件夹values:name: ${{ parameters.name }} # 将用户输入传递给骨架owner: ${{ parameters.owner }}- id: publish-reponame: 发布到GitHubaction: publish:github # 创建并推送到GitHub的内置动作input:repoUrl: ${{ parameters.repoUrl }} # 使用用户输入的仓库URLdescription: ${{ parameters.name }}的微服务defaultBranch: 'main'- id: register-catalog-entityname: 注册到软件目录action: catalog:register # 注册到目录的内置动作input:# 从'publish-repo'步骤的输出中获取新仓库内容的URLrepoContentsUrl: ${{ steps['publish-repo'].output.repoContentsUrl }}catalogInfoPath: '/catalog-info.yaml' # 新仓库中catalog-info.yaml的路径# 成功创建后向用户显示的链接output:links:- title: 在GitHub中打开url: ${{ steps['publish-repo'].output.remoteUrl }} # 新GitHub仓库的链接- title: 在目录中打开icon: catalogentityRef: ${{ steps['register-catalog-entity'].output.entityRef }} # 新目录实体的链接

说明:

  • apiVersionkind:标识此YAML为Scaffolder的Template实体。
  • metadata:模板的基本信息。
  • spec.owner:定义组织中谁维护此模板。
  • spec.parameters用户填写的"步骤"列表。每个步骤是标准的JSONSchema定义,通过ui:属性增强以自定义Backstage表单中的字段显示。
    • nameowner:简单字符串输入。注意ui:field: OwnerPicker是一个自定义字段扩展,帮助用户从软件目录中选择现有实体。
    • repoUrl:使用ui:field: RepoUrlPicker智能输入Git仓库URL,allowedHosts限制为github.com
  • spec.steps核心逻辑!这是Scaffolder将执行的有序action列表
    • fetch:template:从./skeleton目录下载样板代码,并使用用户的nameowner输入进行定制。
    • publish:github:将fetch:template的输出推送到新的GitHub仓库,使用用户输入的repoUrldescription
    • catalog:register:通过指向新仓库中的catalog-info.yaml文件,将新组件注册到软件目录。它使用publish:github动作输出的repoContentsUrl
  • output:定义模板运行成功后向用户显示的链接和信息。

代码骨架(./skeleton/catalog-info.yaml

fetch:template动作引用./skeleton目录。该目录包含新服务的实际样板代码。以下是骨架中catalog-info.yaml的可能内容:

# 这是模板生成代码的一部分
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:# 这些值将由Nunjucks模板引擎填充name: ${{ values.name }} # 如'email-notification-service'description: ${{ values.name }}的微服务# 新组件的所有者(引用目录中的Group实体)owner: default/${{ values.owner }} # 如'default/notifications-team'
spec:type: servicelifecycle: experimental # 或'production'、'staging'等system: default/notification-platform # 所属的逻辑系统

说明:

  • 注意${{ values.name }}${{ values.owner }}。这些是Nunjucks占位符。当fetch:template运行时,会用用户在表单中提供的nameemail-notification-service)和ownernotifications-team)替换它们。这使得模板能动态生成定制文件。

底层原理:软件模板的旅程

当Sam为"邮件通知服务"模板点击"创建"时,Backstage的前端和后端会协调执行一系列步骤。

在这里插入图片描述

说明:

  1. Sam启动模板:Sam使用Backstage的前端插件选择模板并提供必要的输入参数(如project nameownerrepoUrl)。
  2. 前端调用Scaffolder后端:Backstage前端将模板ID和收集的参数发送给Scaffolder后端,这是一个专用于模板执行的后端插件。
  3. Scaffolder后端验证并启动任务Scaffolder后端首先根据模板的模式验证输入。如果有效,则启动新的"Scaffolder任务"以跟踪整个过程。
  4. fetch:template动作:后端执行第一个动作fetch:template。该动作下载模板的代码"骨架"(如示例中的./skeleton目录)到临时工作区。关键的是,它使用Nunjucks模板引擎将这些骨架文件中的占位符(如${{ values.name }})替换为Sam提供的实际值(如email-notification-service)。
  5. publish:github动作:接下来执行publish:github动作。该动作从临时工作区获取完全模板化的代码,与配置的Git提供商(如GitHub API)交互,创建新仓库(如my-org/email-notification-service),并将生成的代码推送到其中。Git提供商返回新仓库的最终URL。
  6. catalog:register动作:最后运行catalog:register动作。它获取新创建的仓库URL(从publish:github步骤的输出中获取),并通过处理其catalog-info.yaml文件将其作为Component实体注册到软件目录。
  7. 成功报告和链接:所有步骤完成后,Scaffolder后端向前端报告任务成功,包括定义的输出链接(如新GitHub仓库的直接链接和新软件目录实体的链接)。
  8. 用户查看结果Sam的Backstage UI更新,显示成功消息并提供可点击的链接,指向新创建并注册的"邮件通知服务"。

代码

支持软件模板的核心组件主要位于@backstage/plugin-scaffolder(前端)和@backstage/plugin-scaffolder-backend(后端)包中。

  • 模板YAML结构Template实体的定义,包括apiVersionmetadataspec.parametersspec.stepsoutput,详见官方文档:

    • 编写模板
    • 目录实体描述符格式 - Kind: Template
  • Scaffolder前端插件:这是渲染"创建"页面、列出模板、从parameters生成表单并显示任务进度和结果的UI部分。

    • 通常通过在packages/app/src/App.tsx中添加import { ScaffolderPage } from '@backstage/plugin-scaffolder';并配置其路由来启用。
  • Scaffolder后端插件:这是协调模板执行的服务器端组件。它处理template.yaml中定义的spec.steps

    • 通过在packages/backend/src/index.ts中添加backend.add(import('@backstage/plugin-scaffolder-backend'));来启用。
    • 它严重依赖后端服务进行日志记录、配置和潜在的数据库访问。
  • 内置动作:Backstage提供了一系列强大的开箱即用动作。

    • fetch:template:用于下载代码骨架并应用模板逻辑。
    • publish:github:与GitHub交互以创建仓库。这需要在app-config.yaml中正确配置集成。
    • catalog:register:与软件目录后端通信以注册新实体。
    • 完整列表及安装方法见内置动作。
  • 自定义动作:如果内置动作不满足需求,可以编写自定义动作以扩展Scaffolder的能力。这涉及使用@backstage/plugin-scaffolder-node中的createTemplateAction

  • 模板语法template.yaml中的${{ parameters.name }}和骨架文件中的${{ values.name }}等表达式使用Nunjucks模板。这个强大的引擎允许在模板中进行动态数据注入和条件逻辑。

    • 更多信息见模板语法。
  • 自定义字段扩展:为更定制化的用户输入,可以编写自定义字段扩展(如OwnerPickerRepoUrlPicker)以增强表单体验。

结论

在本章中,我们探讨了软件模板(Scaffolder),这是Backstage中改变游戏规则的功能,它自动化并标准化了新软件组件的创建

我们了解到模板由其parameters(用户输入)和steps(Scaffolder后端执行的动作)定义,这些步骤利用模板引擎生成定制代码。通过理解如何定义模板、使用内置动作和自定义用户体验,我们现在掌握了让开发者快速、一致地创建新项目并遵循组织最佳实践的工具。

接下来,我们将深入探讨另一个管理软件生态系统的强大功能:TechDocs,Backstage的"文档即代码"解决方案。

http://www.dtcms.com/a/481810.html

相关文章:

  • 链表操作教学工具
  • 珠海市网站建设的公司网站安全维护
  • PC端AI推理存储IO流量剖析
  • 如何在AutoCAD中管理GIS属性表?
  • 消防模块-图形识别快速匹配
  • 备案网站名怎么写前端微信小程序开发
  • 使用Spring Boot构建多维度配置层
  • vps 可以做多个网站吗沈阳营销网站建设
  • 上传文件相关业务,采用策略模式+模版方法模式进行动态解耦
  • Unity3d中Tab控件的实现
  • 桥梁主动防撞预警系统方案
  • 【node】运行windows7下的高版本node.js
  • 解密NLP:从入门到精通
  • 如何说课网站建设当地公交建设公司的官网
  • 哪里有网站开发服务器西安关键词排名提升
  • npx 与 npm 区别
  • diffusion model(0.5) score-SDE 关于score function与noise的关系
  • leetcode724 寻找数组的中心下标
  • AI用户洞察新纪元:atypica.AI如何重塑商业决策逻辑
  • 彻底解决 Zip4j 解压中文文件名乱码问题(含混合编码与 Mac 特殊情况)
  • 河北农业网站建设公司凡科互动官网登录
  • 企业网站建设的成本构成吉林市网站建设招标
  • git push 报错 push rejected (一文读懂并解决)
  • 从缓存到分库分表:MySQL 高并发海量数据解决方案全解析
  • 苍穹外卖-缓存套餐 Spring Cache day07
  • 垂直电商网站建设方案wordpress主题开发时间
  • 报告工具更新!Word附注一键期末转期初
  • 优化A7M4相机直播图像传输:避免质量损失,实现端到端高保真
  • 平替MongoDB金仓多模数据库在电子证照国产化中的实践与优势
  • AWS WAF 深度体验:全新控制台,开启云原生WAF与CloudFront无缝联防新纪元