ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Backstage 架构决策记录(ADR)编写指南:基于 adr000-template 模板与全仓库 ADR 实践的深度解析

Backstage 架构决策记录(ADR)编写指南:基于 adr000-template 模板与全仓库 ADR 实践的深度解析 Backstage 架构决策记录ADR编写指南基于 adr000-template 模板与全仓库 ADR 实践的深度解析【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage导读本文以 Backstage 仓库中用于沉淀架构决策的 adr000-template.md 模板为核心结合 ADR 总览页 的流程规范以及仓库内 ADR001 至 ADR015 共 15 份真实决策记录作为实践佐证系统讲解为什么要写 ADR、模板每个字段如何填写、决策如何评审与更替。读完本文你将能够为 Backstage 项目或你自己的开发者门户项目起草一份结构规范、事实清楚、可评审可追溯的架构决策记录。一、什么是 ADRBackstage 如何沉淀架构决策在 Backstage 仓库的 docs/architecture-decisions 目录下存放着这个开源项目做出过的所有重大架构决策。每一份决策被称为Architecture Decision RecordADR其总览页 index.md 开宗明义The substantial architecture decisions made in the Backstage project live here.Backstage 项目中所有实质性的架构决策都存放在这里。这些记录的核心价值在于三个方面作为团队的重大决策参考基准reference point、帮助新成员快速 onboarding、以及为所有关注项目的人提供决策上下文。这三点在 ADR001: Architecture Decision Record (ADR) log 中得到了原汁原味的阐述There is a need to store big decisions made in a log as a reference point for the team, help with onboarding new members, and give context to others interested in the project.需要把重大决策记录在日志中作为团队的参考基准帮助新成员快速上手并为其他关注项目的人提供背景信息。需要特别强调的是ADR 是一种只增不改的日志体系index.md 明确规定 Records are never deleted but can be marked as superseded by new decisions or deprecated——记录永远不会被删除但可以被新的决策标记为 superseded被取代或 deprecated废弃。这种设计保证了决策演进的历史完整可追溯。从模板的注释可知Backstage 的 ADR 模板源自 Michael Nygard 关于架构决策记录的开创性实践该注释保留在 adr000-template.md 中而 Backstage 在其基础上结合自身开源项目的协作方式做了定制。二、逐字段拆解 adr000-template 模板adr000-template.md 是创建新 ADR 的标准起点全文结构非常精简一段 YAML Front Matter 加三个正文章节。下面逐一拆解每个部分的写作要点。2.1 Front Matter元数据区模板的 Front Matter 包含三个字段--- id: adrs-adr000 title: ADR000: [TITLE] description: Architecture Decision Record (ADR) for [TITLE] [DESCRIPTION] ---id文档的唯一标识符采用adrs-adrNNN的命名模式与目录中adrNNN-*.md的文件名一一对应title采用ADR000: [TITLE]的格式其中编号与 id 保持一致description一句话概括该 ADR 的主题用于文档检索和搜索引擎收录。模板头部还保留了一条关键注释规定了 ADR 文件名的命名规范These documents have names that are short noun phrases. For example, ADR001: Deployment on Ruby on Rails 3.0.10 or ADR009: LDAP for Multitenant Integration.也就是说文件名的主题部分必须是简短的名词短语例如 Deployment on Ruby on Rails 3.0.10在 Ruby on Rails 3.0.10 上部署或 LDAP for Multitenant Integration用于多租户集成的 LDAP。对照仓库实际文件adr002-default-catalog-file-format.md、adr010-luxon-date-library.md、adr015-jsx-loader-structure.md等均严格遵守了这一简短名词短语的命名约定。2.2 Context背景价值中立地描述决策面临的张力模板对Context章节给出了明确的写作指引This section describes the forces at play, including technological, political, social, and project local. These forces are probably in tension, and should be called out as such. The language in this section is value-neutral. It is simply describing facts.翻译过来即本小节需要描述决策时所面对的各种作用力forces包括技术层面的、组织层面的、社会层面的以及项目自身的因素。这些力量之间往往存在张力in tension应当如实点明。语言上要保持价值中立value-neutral只陈述事实不做价值评判。仓库中的优秀范例是 ADR010: Use the Luxon Date Library 的 Context 部分它把技术张力描述得非常清晰Backstage 中日期格式化如 a day ago和日期计算非常常见而原生 JavaScriptDate对象不支持这些能力流行的 Moment.js 虽能填补空白但存在包体积大large bundle sizes和可变状态mutable state问题更关键的是 Moment.js 项目正在被官方停止维护being sunset官方推荐使用更现代的替代库。三个事实层层递进最后自然引出需要标准化日期时间库的结论。这就是一份优秀的 Context 应有的样子只摆事实、不预设立场让读者自己得出确实需要做决策的判断。再看 ADR004: Module Export Structure 的 Context它以两个设问句起笔直击痛点Is the export in this module also exported by the package?这个模块里的导出是否也被包导出了 What is exported from this directory?这个目录导出了什么随后描述现状backstage/core-components等包的导出规模日益庞大却没有任何统一的导出结构模式——有的从包级深层 re-export有的按目录浅层 re-export有的用*有的逐个枚举符号。这种混乱和不可预测性让模块边界的推理变得困难。2.3 Decision决策用主动语态写清我们将怎么做模板对Decision章节的指引只有一句话This section describes our response to these forces. It is stated in full sentences, with active voice. We will ...即本节描述我们对上述作用力的回应必须用完整的句子、主动语态active voice来写句式以 We will ...我们将……开头。对照仓库实践ADR010 的决策写得简洁有力We will use Luxon as the standard date library within Backstage.并补充了选择理由Luxon 提供了与 Moment.js 类似的功能集和 API但通过不可变性immutability和现代 JavaScript API如 Intl改进了设计从而在提供完整功能的同时减小包体积且无需额外库来完成常见的日期时间任务。而 ADR009: Entity References 则示范了决策包含具体格式规范的写法——当决策本身就是一套技术方案时应把方案细节完整写入。它规定人类手写的实体引用字符串格式为[kind:][namespace/]name方括号表示可选由一至三个部分按固定顺序组成中间不加额外编码机器间交换格式需要更强表达力时可使用嵌套结构kind/namespace/name其中仅name必填前端 URL 中引用实体必须采用:namespace/:kind/:name三段式三段在任何情况下都缺一不可——因为字符串形式使用了 URL 不安全的字符不适合作为 URL 单段使用。这类决策即规范的 ADR是模板 Decision 章节最实用的形态。2.4 Consequences后果正负中立后果都要列模板对Consequences章节的指引值得反复咀嚼This section describes the resulting context, after applying the decision. All consequences should be listed here, not just the positive ones. A particular decision may have positive, negative, and neutral consequences, but all of them affect the team and project in the future.要点有二一是要描述决策实施后形成的新上下文resulting context二是所有后果都要列出不只是正面后果——正面、负面、中立的后果都会在未来的团队和项目中产生影响。ADR010 示范了正面中立的组合写法所有核心包和插件在原生Date难以完成的操作上统一使用 Luxon约束只使用一个日期库避免学习多套 API收益单一日期库减小包体积收益。ADR015: Types and naming for element and component options 的 Consequences 则展示了需要付出迁移成本的诚实写法We will update all APIs for the new frontend system in thebackstage/frontend-*packages. We will not update any of the existing APIs for the old frontend system in thebackstage/core-*packages.——明确划定了改造范围新前端系统和不动范围旧前端系统避免读者误以为全仓库立即统一。这种既说做什么、也说不做什么的写法是 Consequences 章节的高级形态。三、ADR 的完整生命周期从创建到被取代ADR 不是一次性写就的静态文件它在 index.md 中定义了一套完整的生命周期流程。3.1 创建一份新 ADRindex.md 给出了创建 ADR 的七个步骤将 adr000-template.md 复制为docs/architecture-decisions/adr000-my-decision.mdmy-decision部分要有描述性不要自行分配 ADR 编号按照模板中的指南填写 ADR 内容提交 Pull Request回应并整合社区的评审反馈最终为 ADR 分配编号编号是在评审通过后由维护者统一分配的避免了多人并行提交时编号冲突将 ADR 路径添加到微站点侧边栏配置 microsite/sidebars.ts将 ADR 路径添加到 mkdocs.yml然后合并 Pull Request。最后两步说明 Backstage 文档体系中存在两条渲染管线microsite基于 Docusaurus和 mkdocs新增文档需要同时注册到两处才能在对应站点上被浏览到。3.2 ADR 的取代Superseding当一项新决策取代旧决策时旧 ADR 的状态需要被修改为 superseded by ADR-XXXX并链接到新 ADR。结合记录永不删除的规则这形成了一条完整的决策演进链旧的决策内容永久保留说明当初为什么这么定新的决策在上面打补丁或推翻重来说明现在为什么改。四、模板在仓库中的真实落地三份可对照学习的范例与其抽象讨论怎么写不如对照仓库中三份形态各异的真实 ADR看看模板的三个章节在实际决策中是如何被组织成文的。4.1 ADR009规范型决策的写法ADR009: Entity References 属于制定接口规范型决策。它的结构是Background指出ADR002虽然定义了 catalog 文件格式但没有说明如何表达对其他实体的引用且前端 URL 中的实体引用方式也存在混乱并注明问题来源于 Issue 1947 的讨论两个规范小节YAML 文件中的实体引用 / URL 中的实体引用直接给出字符串格式[kind:][namespace/]name、嵌套结构、URL 格式:namespace/:kind/:name的完整定义对于机器可读的嵌套结构还特意声明 All other possible key values in this structure are reserved for future use该结构中的所有其他键值均保留给未来使用体现了规范的扩展性设计。这种写法把决策直接等同于发布了什么规范非常适合需要跨组件、跨团队对齐接口语义的场景。4.2 ADR015带代码示例的决策写法ADR015: Types and naming for element and component options 示范了如何用代码把决策钉死。它规定了五种组件/元素选项模式及其适用场景模式类型签名适用场景Simple elementelement: JSX.Element同步 JSX 元素无需懒加载Simple componentcomponent: (props) JSX.Element \| null同步组件无需懒加载Async element loaderloader: () PromiseJSX.Element单个实例、无需传 props 的异步元素首选Async component loaderloader: () Promise(props) JSX.Element \| null需要传 props 或多个实例且需懒加载Any component loader同步/异步二选一的 loader 联合类型同步加载与懒加载都需要更为关键的是它用一小段实现代码揭示了决策背后的工程约束消费 loader 时必须无条件用React.lazy包裹因为不能在 render 函数内调用React.lazy也就无法先调用 loader 判断返回的是否为 Promiseconst LazyComponent React.lazy(() Promise.resolve(options.loader()).then(loaded ({ default: loaded })), );这种决策 关键实现陷阱的组合让后来者不仅知道选哪种还知道为什么必须这么实现。4.3 ADR003 / ADR006编码规范型决策的写法ADR003: Avoid Default Exports and Prefer Named Exports 和 ADR006: Avoid React.FC and React.SFC 属于统一代码风格型决策其共同特点是Context 里充分阐述反对方案的论据Decision 里给出应该/不应该的明确判据并附上正反代码示例。以 ADR003 为例它总结了对 default export 的五大批评增加间接性import TheListThing from not-a-list-thing、阻碍 IDE 的自动重命名与重构、助长拼写错误导入名完全由使用者定义、在 CommonJS interop 中丑陋、以及破坏 re-export 造成命名冲突。同时给出命名导出的收益IDE 的 Find All References 和 Go To Definition 可用、grep 搜索更轻松。最后的决策保留了唯一例外——React.lazy模块并给出了绕开 default 的 workaroundconst Component React.lazy(() import(../path/to/Component).then(m ({ default: m.Component })), );ADR006 则直接给出正反对照代码。避免的写法是隐式注入children的FCBadProps推荐的写法是显式声明children?: React.ReactNode或使用PropsWithChildren{ text: string }。这类 ADR 的 Consequences 通常带有明确的收尾动作——ADR003 声明将添加 lint 规则帮助迁移ADR006 声明将从代码库中逐步移除现有的 React.FC 和 React.SFC 用法ADR012Luxon 的toLocaleString与日期预设规范也提到审查当前所有展示日期时间的 UI 位置并统一更新。规范从纸面落到工具才能真正长期生效。五、把 ADR 模板用到你自己的 Backstage 项目中如果你正在构建自己的 Backstage 实例例如通过npx backstage/create-app创建的应用完全可以复用这套 ADR 机制来管理你的自定义插件与后端服务的架构决策。操作上建议引入模板把 adr000-template.md 复制到你自己仓库的docs/architecture-decisions/目录并保留 Front Matter 的id/title/description三段式遵循命名文件名使用adrNNN-简短名词短语.md的格式如adr001-my-portal-db-choices.md编号可在提交评审后由团队维护者统一分配按三章写作Context 价值中立地罗列事实与张力Decision 用 We will ... 主动语态给出回应Consequences 同时列出正面、负面与中立的后续影响只增不改已合入的 ADR 永不删除被新决策取代时在原文档标注 superseded by ADR-XXXX 并链接到新文档配套工具落地像 Backstage 用 lint 规则巩固 ADR003/ADR006 的规范那样为你的自定义代码补充对应的 lint 配置让决策真正约束日常开发。六、结语一份 ADR 模板的价值不在于它的篇幅而在于它强制写作者完成的三个动作冷静描述事实与张力Context、清晰承诺行动Decision、诚实预估全部后果Consequences。Backstage 用 15 份真实决策记录证明了这套方法论在大型开源项目中的有效性——从 catalog 文件格式 到 实体引用规范从 Luxon 日期库选型 到 前端系统组件选项类型约定每一份决策都能在模板的三个章节中找到清晰的落点。如果你要在 Backstage 生态中做出任何影响面较大的技术选择从复制这份模板开始就是最稳妥的第一步。【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表