本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
GSoD 2020:改善 API 参考体验
编者按:在我三年半前加入 Kubernetes 文档团队以来,更好的 API 参考一直是我的目标。Philippe 取得了巨大的成功。然而,Philippe 在这个项目中不仅提供了更好的 API 参考,他还体现了 Kubernetes 社区最优秀的一面:通过协作实现卓越,以及使社区自身变得更好的过程。感谢 Google Season of Docs 使 Philippe 的工作成为可能。—Zach Corleissen
引言
Google Season of Docs 项目将开源组织和技术作家聚集在一起,紧密合作完成一个特定的文档项目。
我被 CNCF 选中,负责 Kubernetes 文档工作,特别是让 API 参考文档更易于访问。
我是一名软件开发者,对文档系统有着浓厚的兴趣。20世纪90年代末,我开始将 Linux-HOWTO 文档翻译成法语。不知不觉中,我学会了文档系统。最终,我写了一个 Linux-HOWTO 来帮助文档编写者学习当时用于编写文档的语言——LinuxDoc/SGML。
不久之后,Linux 文档采用了 DocBook 语言。我帮助一些作者用这种格式重写他们的文档;例如,《高级 Bash 脚本指南》。我还参与了 GNU `makeinfo` 程序的工作,添加了 DocBook 输出,使得将 GNU Info 文档转换为 DocBook 格式成为可能。
背景
Kubernetes 网站使用 Hugo 构建,文档以 Markdown 格式编写在网站仓库中,并使用了Docsy Hugo 主题。
现有的 API 参考文档是一个从 Kubernetes OpenAPI 规范生成的巨大 HTML 文件。
就我而言,我一直希望通过以下方式让 API 参考更易于访问:
- 为每个 Kubernetes 资源构建独立的页面
- 调整格式以适应移动设备阅读
- 重用网站的资源和主题来构建、集成和显示参考页面
- 允许搜索引擎引用页面内容
大约一年前,我开始着手开发生成当前唯一 HTML 页面的生成器,以添加 DocBook 输出,这样 API 参考就可以首先以 DocBook 格式生成,然后通过 DocBook 处理器转换为 PDF 或其他支持的格式。最初的结果是一些API 参考的电子书文件和一本自出版的纸质书。
后来我决定给这个生成器添加另一个输出,以生成 Markdown 文件并创建一个带有 API 参考的网站。
当 CNCF 提议一个 Google Season of Docs 项目来处理 API 参考时,我提交了申请,然后成功匹配。
项目
swagger-ui
提出此项目的 CNCF 成员最初的想法是测试`swagger-ui` 工具,并尝试使用此标准工具来文档化 Kubernetes API 参考。
由于 Kubernetes API 比许多其他 API 大得多,因此有必要编写一个工具,按 API 组拆分完整的 API 参考,并在文档网站中插入多个 `swagger-ui` 组件,每个 API 组一个。
通常,开发者通过使用特定的 HTTP 动词调用带有特定参数的端点并等待响应来使用 API。`swagger-ui` 界面就是为此用途而构建的:该界面显示端点列表及其关联的动词,以及每个端点的参数和响应格式。
Kubernetes API 大部分时候以不同的方式使用:用户创建包含 YAML 格式资源定义的清单文件,并使用 `kubectl` CLI 将这些清单“应用”到集群。在这种情况下,最重要的信息是作为参数和响应的结构(Kubernetes 资源)的描述。
由于这一特殊性,我们意识到很难调整 `swagger-ui` 接口来满足 Kubernetes API 用户,因此放弃了这一方向。
Markdown 页面
项目的第二阶段是调整我为创建 k8sref.io 网站所做的工作,将其包含到官方文档网站中。
主要改动包括:
- 使用 Go 模板来表示输出页面,这样非开发者就可以在不编辑生成器代码的情况下调整生成的页面
- 创建一个新的自定义短代码,以便轻松从网站内部创建指向 API 参考特定页面的链接
- 改进 API 参考各节之间的导航
- 将生成器代码添加到包含不同参考生成器的 Kubernetes GitHub 仓库中
所有讨论和已完成的工作都可以在网站的 pull request #23294 中找到。
将生成器代码添加到 Kubernetes 项目是在 kubernetes-sigs/reference-docs#179 中完成的。
以下是即将包含在官方文档网站中的新 API 参考的功能:
- 资源按类别(工作负载、服务、配置与存储、认证、授权、策略、扩展、集群)进行分类。此结构可通过简单的 `toc.yaml` 文件配置。
- 每个页面都显示第一级的相关资源;例如:Pod、PodSpec、PodStatus、PodList
- 大多数资源页面都会内联显示相关定义;例外情况是当这些定义是多个资源共有的,或者过于复杂而无法内联显示时。在旧方法中,您必须点击超链接才能阅读每个额外细节。
- 一些广泛使用的定义,例如 `ObjectMeta`,在特定页面中进行了文档化。
- 必填字段已标明,并置于首位。
- 资源的字段可以使用 `fields.yaml` 文件进行分类和排序。
- `map` 字段已标明。例如,`Pod` 的 `.spec.nodeSelector` 是 `map[string]string`,而不是 `object`,使用的是 `x-kubernetes-list-type` 的值。
- 补丁策略已标明。
- `apiVersion` 和 `kind` 显示值,而不是 `string` 类型。
- 在参考页面顶部,页面会显示从 Go 程序中使用这些资源所需的 Go 导入语句。
该工作目前暂停,等待 1.20 版本发布。当版本发布并集成后,API 参考将可在 https://kubernetes.ac.cn/docs/reference/ 访问。
未来工作
仍有一些需要改进的地方,特别是:
- 一些 Kubernetes 资源嵌套很深。内联这些资源的定义使得它们难以理解。
- 创建的 `shortcode` 使用页面的 URL 来引用资源页面。如果文档编写者可以通过资源的组和名称来引用资源,将会更容易。
鸣谢
我要感谢我的导师 Zach Corleissen 以及首席作家 Karen Bradshaw、Celeste Horgan、Tim Bannister 和 Qiming Teng,他们在整个赛季中指导了我。他们都非常鼓励我,并给了我大量宝贵的建议。