自定义模型
Halo 自定义模型参考 Kubernetes 自定义资源设计,用于存储插件业务数据,并自动获得 CRUD API、权限和查询能力。本文描述模型本身;需要编写额外业务接口时参考自定义 API。
定义模型
自定义模型继承 AbstractExtension,并通过 @GVK 声明 API group、version、kind 和资源名称:
group应使用插件或组织控制的域名形式,避免与其他插件冲突。version与 group 组成apiVersion。kind是资源类型名。plural和singular必须小写,并用于 API 路径。
apiVersion、kind 和 metadata 已由 AbstractExtension 提供。插件通常定义 spec 表示期望状态,并在需要时定义 status 表示控制器维护的实际状态。
注册模型
在插件启动时注册 Scheme,并在停止时对称注销:
注册 Scheme 不会自动实现业务状态维护。需要响应资源变化时,另行注册自定义模型控制器。
声明预置对象
插件可以在 src/main/resources/extensions 中提供 YAML 对象。插件启动后,Halo 会按 apiVersion、kind 和 metadata.name 创建或更新资源:
文件名可以自定义,也可以使用 --- 在同一文件中声明多个对象。
默认情况下,同名对象会在插件再次启动时更新。需要保留用户修改时,可以添加:
带该标签的预置资源不会被启动流程覆盖,也不会在插件停止时按普通预置资源清理。完整边界见插件生命周期。
校验对象
Halo 根据模型生成 OpenAPI Schema,并在写入对象时校验结构和约束。使用 @Schema 声明必填、长度和数值范围等约束:
description 和 example 主要用于 API 文档;是否形成运行时约束取决于对应 OpenAPI Schema 关键字。
配置索引
查询或排序的字段必须注册为索引。Halo 2.22.0 起应使用 IndexSpecs.single() 或 IndexSpecs.multi():
- 单值索引可以返回
null。 - 多值索引返回
Set<keyType>。 keyType必须实现Comparable。- 同一模型中的索引名称必须唯一。
Halo 已为以下字段建立索引,不要重复声明:
metadata.name,唯一索引metadata.labelsmetadata.creationTimestampmetadata.deletionTimestamp
索引会增加写入和存储成本,只为实际查询或排序的字段创建。
元数据命名
metadata.name
metadata.name 是同一资源类型中的唯一标识:
- 不超过 253 个字符。
- 只能包含小写字母、数字和
-。 - 以字母或数字开头和结尾。
labels
labels 用于标识和查询对象,因此会自动建立索引。插件应使用自己控制的 DNS 子域名前缀,例如 example.com/category,不能使用 Halo 保留的 halo.run 等前缀。
名称部分最多 63 个字符,可包含字母、数字、-、. 和 _,并以字母或数字开头和结尾。不要在 labels 中存放凭据或个人敏感信息;不需要查询的数据应放在 annotations 中。
annotations
annotations 与 labels 使用相同的 <prefix>/<name> 键格式,但不会自动建立索引。它适合保存不参与查询的附加信息;仍然不能用于存放凭据或个人敏感信息。
使用自动生成的 API
注册模型后,Halo 自动提供以下资源 API:
列表 API 支持 page、size、sort、labelSelector 和 fieldSelector。排序与字段选择器只能使用已建立索引的字段:
该请求查询 label type=staff 且名称为 halo 的对象,并按 metadata.name 降序返回第一页。
标签选择器
labelSelector=type=staff:值等于stafflabelSelector=type!=staff:值不等于stafflabelSelector=!type:不存在typelabelSelector=type:存在type
字段选择器
fieldSelector=metadata.name=halo:值等于halofieldSelector=metadata.name!=halo:值不等于halofieldSelector=metadata.name=(halo,halo2):值在集合中
服务端代码中的响应式查询方式见 ReactiveExtensionClient。
自定义 API
自动生成的 CRUD API 不能覆盖聚合查询或业务动作时,使用自定义 API。原有 custom-api-group-spec 锚点保留在本节,已有链接无需修改。
自定义 API 请求校验
自定义 API 的 Bean Validation 内容已移至校验请求体。本节保留原有锚点,已有链接无需修改。