ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Backstage Catalog 数据模型完全解析:基于 @backstage/catalog-model 的 Entity、实体引用与校验体系

Backstage Catalog 数据模型完全解析:基于 @backstage/catalog-model 的 Entity、实体引用与校验体系 Backstage Catalog 数据模型完全解析基于 backstage/catalog-model 的 Entity、实体引用与校验体系【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage导读backstage/catalog-model是 Backstage 软件目录Software Catalog的数据模型与校验核心包它定义了目录中所有实体Entity的 TypeScript 类型、内置 KindComponent、API、System 等的 spec 结构、实体引用Entity Ref与 Location Ref 的解析规则以及一整套用于验证实体合法性的策略与校验函数。本篇文章以该包公开 API 报告文件 packages/catalog-model/report.api.md 为主体骨架结合仓库源码逐层拆解其设计帮助你彻底理解 Backstage 目录实体的底层格式并能在实际编写 catalog-info.yaml、开发自定义 Kind 与校验策略时直接复用这些知识。一、Entity目录中一切实体的统一结构在 Backstage 中无论哪种 Kind 的实体最终都收敛为同一个基础 TypeScript 类型Entity。其定义位于 packages/catalog-model/src/entity/Entity.tsexport type Entity { apiVersion: string; // 该实体所遵循的规格格式版本 kind: string; // 实体高层类型如 Component、API、System metadata: EntityMeta; // 与实体相关的元数据 spec?: JsonObject; // 描述实体本身的规格数据 relations?: EntityRelation[]; // 该实体与其他实体的关系 };从 API 报告来看这一结构与EntityEnvelope形成对照——后者是只含apiVersion、kind和简化版metadata仅name与可选namespace的信封形态用于在完整实体不可用或不宜暴露时例如数据尚未处理完毕进行轻量传递与校验对应实现见 packages/catalog-model/src/entity/EntityEnvelope.ts 与报告中的entityEnvelopeSchemaValidator。1.1 EntityMeta实体元数据字段详解EntityMeta是实体元数据的类型定义同样位于 Entity.ts各字段语义如下字段类型说明uidstring全局唯一 ID由服务端生成创建时不可由用户设置etagstring每次更新都会变化的不透明字符串可用于乐观并发控制namestring实体技术标识在同一namespace kind组合内必须唯一会出现在 URL、数据库与实体引用中namespacestring实体所属命名空间缺省时回落到defaulttitlestring面向 UI 的展示名格式限制比name宽松descriptionstring单行简要描述labelsRecordstring, string键值对形式的标识性信息annotationsRecordstring, string键值对形式的辅助性信息非标识性tagsstring[]用于分类的单值字符串列表linksEntityLink[]与实体相关的外部超链接列表其中EntityLink包含url必填、title、icon、type四个可选字段EntityRelation则由type关系类型与targetRef目标实体的实体引用字符串组成。1.2 内置 Annotation 常量报告的注解常量定义在 packages/catalog-model/src/entity/constants.tsANNOTATION_VIEW_URL backstage.io/view-url从目录页跳转到实体页的链接ANNOTATION_EDIT_URL backstage.io/edit-url从目录页跳转到实体编辑页的链接ANNOTATION_LOCATION backstage.io/managed-by-location声明实体由哪个 location 托管ANNOTATION_ORIGIN_LOCATION backstage.io/managed-by-origin-location声明实体的原始来源 locationANNOTATION_SOURCE_LOCATION backstage.io/source-location声明实体源码所在位置ANNOTATION_KUBERNETES_API_SERVER、ANNOTATION_KUBERNETES_API_SERVER_CA、ANNOTATION_KUBERNETES_AUTH_PROVIDER三个 Kubernetes 相关常量在当前版本中已标记为 deprecated注释明确要求改从backstage/plugin-kubernetes-common导入。DEFAULT_NAMESPACE default是同一文件中的核心常量实体未显式声明 namespace 时统一回落到该值。二、内置 Kind 及其 spec 结构backstage/catalog-model为每个标准 Kind 提供了xxxEntityV1alpha1接口类型与对应的xxxEntityV1alpha1Validator。这些类型的apiVersion均限定为backstage.io/v1alpha1 | backstage.io/v1beta1kind字段为对应的字面量字符串。各 Kind 的 spec 结构如下Kindspec 字段说明Componenttype,lifecycle,owner必填subcomponentOf,providesApis,consumesApis,dependsOn,dependencyOf,system可选单个软件组件APItype,lifecycle,owner,definition必填system可选一个 API 接口定义Resourcetype,owner必填dependsOn,dependencyOf,system可选支撑组件运行的基础资源Systemowner必填domain,type可选由组件、API、资源组成的系统Domainowner必填subdomainOf,type可选业务域可包含多个系统Grouptype,children必填profile.displayName,profile.email,profile.picture,parent,members可选组织架构中的用户组UsermemberOf可选profile.displayName,profile.email,profile.picture可选单个用户Locationtype,target,targets,presence: required \| optional均可选描述从何处读取实体定义以 ComponentEntityV1alpha1.ts 为例其类型定义与 API 报告完全一致同文件还展示了这些 Kind 在新版目录模型层Catalog Model Layer中的注册方式通过createCatalogModelLayer声明 Kind 的名称kind: Component、版本v1alpha1/v1beta1以及从 spec 字段推导关系的 selector 规则——例如spec.owner会生成ownedBy关系默认指向 Group/Userspec.providesApis生成providesApi关系spec.system生成partOf关系等。报告同时导出了一组类型守卫函数isApiEntity、isComponentEntity、isDomainEntity、isGroupEntity、isLocationEntity、isResourceEntity、isSystemEntity、isUserEntity用于在运行时判断实体的具体 Kind。三、实体引用Entity Ref定位实体的统一寻址方式实体引用是 Backstage 中描述哪个实体的标准字符串格式语法为[kind:][namespace/]name例如component:default/my-service。API 报告围绕它导出了三组函数核心实现在 packages/catalog-model/src/entity/ref.ts。3.1 parseEntityRef解析实体引用export function parseEntityRef( ref: string | { kind?: string; namespace?: string; name: string }, context?: { defaultKind?: string; defaultNamespace?: string }, ): CompoundEntityRef;传入字符串或对象形式的引用返回CompoundEntityRef{ kind, namespace, name }三元组字符串解析逻辑见 ref.ts会同时查找:与/的位置若/在:之前则整个字符串视为 namekind、namespace任一为空段都会抛出TypeErrorcontext提供默认值defaultNamespace缺省为DEFAULT_NAMESPACE若最终 kind 缺失会抛出缺少 kind例如未以 component: 开头的错误。3.2 stringifyEntityRef 与 getCompoundEntityRefstringifyEntityRef接收实体或{ kind, namespace, name }将其序列化为规范化字符串格式为${kind.toLowerCase()}:${namespace.toLowerCase()}/${name.toLowerCase()}自动补齐默认命名空间且全部转小写——这是该函数被文档明确标注通常不是向用户展示实体引用的最佳方式的原因见 ref.tsgetCompoundEntityRef则从Entity直接提取三元组namespace缺省回落到default。四、Location Ref实体的来源定位Location Ref 的字符串形式为type:target例如url:https://github.com/.../catalog-info.yaml。相关实现集中在 packages/catalog-model/src/location/helpers.tsparseLocationRef(ref)解析字符串为{ type, target }。实现中有几处值得注意的防御性校验target 必须非空http:/https:开头的引用会被拒绝并要求显式加url:前缀target 为javascript:协议时直接抛错helpers.tsstringifyLocationRef(ref)反向序列化同样校验 type/target 非空并拦截javascript:协议getEntitySourceLocation(entity)从实体的backstage.io/source-location注解读取位置若不存在则回落到backstage.io/managed-by-location两者都缺失时抛出Entity 缺少 location错误helpers.ts。五、关系Relation常量体系实体之间的关系通过EntityRelation表达报告导出了全部关系类型常量源码定义于 packages/catalog-model/src/kinds/relations.ts并遵循三条命名规则文件头部注释最多两个单词、源 Kind 关系 目标 Kind读起来符合英文语义、正反关系保持对称如ownedBy/ownerOf。完整关系常量表常量值语义RELATION_OWNED_BY/RELATION_OWNER_OFownedBy/ownerOf归属关系正反向RELATION_CONSUMES_API/RELATION_API_CONSUMED_BYconsumesApi/apiConsumedBy组件消费 APIRELATION_PROVIDES_API/RELATION_API_PROVIDED_BYprovidesApi/apiProvidedBy组件提供 APIRELATION_DEPENDS_ON/RELATION_DEPENDENCY_OFdependsOn/dependencyOf依赖关系正反向RELATION_PARENT_OF/RELATION_CHILD_OFparentOf/childOf父子层级如 Group 组织树RELATION_HAS_MEMBER/RELATION_MEMBER_OFhasMember/memberOf组成员关系RELATION_HAS_PART/RELATION_PART_OFhasPart/partOf整体/部分关系组件属系统、系统属域等这些常量与各 Kind 的 spec 字段如spec.owner、spec.providesApis、spec.memberOf一一对应构成了目录实体之间关系图的静态语义基础。六、校验体系从字段到实体的多层防线backstage/catalog-model提供了三层校验能力底层校验函数、面向实体整体/字段的校验器以及可组合的实体策略Entity Policy。6.1 校验函数与 ValidatorsCommonValidatorFunctionsCommonValidatorFunctions.ts提供与 Kubernetes 无关的通用校验isNonEmptyString非空字符串isValidString为已弃用别名isValidDnsLabel1~63 字符匹配^[a-z0-9](?:\-[a-z0-9])*$isValidDnsSubdomain1~253 字符按.分段后每段都是合法 DNS labelisValidUrl使用new URL(value)构造判断isJsonSafe序列化往返后与原始值相等isValidPrefixAndOrSuffix按分隔符拆成最多两段分别校验isValidTag1~63 字符匹配^[a-z0-9#](\-[a-z0-9#])*$已弃用。KubernetesValidatorFunctionsKubernetesValidatorFunctions.ts提供isValidAnnotationKey/Value、isValidLabelKey/Value、isValidApiVersion、isValidKind、isValidNamespace、isValidObjectName等校验规则对齐 Kubernetes 对象命名规范。makeValidatormakeValidator.ts将上述函数组合成Validators接口对象默认全部取自KubernetesValidatorFunctions其中isValidTag以内联正则实现overrides参数允许按需替换任意单项。Validators接口本身包含 9 个方法isValidApiVersion、isValidKind、isValidEntityName、isValidNamespace、isValidLabelKey、isValidLabelValue、isValidAnnotationKey、isValidAnnotationValue、isValidTag。6.2 Schema 校验器报告导出三个高阶校验器工厂entitySchemaValidator(schema?)基于 JSON Schema 校验完整实体返回(data: unknown) TentityEnvelopeSchemaValidator(schema?)基于简化 envelope 校验实体信封entityKindSchemaValidator(schema)按 Kind 的 JSON Schema 校验返回(data: unknown) T | false不匹配时返回false而非抛错。这些函数底层由 AJV 驱动相关 JSON Schema 文件位于 packages/catalog-model/src/schemaEntity.schema.json、EntityEnvelope.schema.json、EntityMeta.schema.json、common.schema.json以及各 Kind 的*.v1alpha1.schema.json。KindValidator接口则抽象了单 Kind 校验器仅含check(entity: Entity): Promiseboolean一个方法各xxxEntityV1alpha1Validator均通过ajvCompiledJsonSchemaValidator(jsonSchema)生成见 ComponentEntityV1alpha1.ts。6.3 实体策略EntityPolicyEntityPolicy接口只含一个方法enforce(entity: Entity): PromiseEntity | undefined返回undefined表示该策略不适用。API 报告内置了五类策略策略作用源码SchemaValidEntityPolicy用内置 JSON Schema 校验实体整体结构SchemaValidEntityPolicy.tsFieldFormatEntityPolicy逐字段校验格式apiVersion、kind、name、namespace、labels、annotations、tags、links并在校验失败时给出带格式期望值的错误信息FieldFormatEntityPolicy.tsNoForeignRootFieldsEntityPolicy禁止实体根级出现未知字段可传入已知字段白名单NoForeignRootFieldsEntityPolicy.tsDefaultNamespaceEntityPolicy为缺少 namespace 的实体补充默认命名空间默认为defaultDefaultNamespaceEntityPolicy.tsGroupDefaultParentEntityPolicy为 Group 实体设置默认父级构造参数parentEntityRef传入父实体引用GroupDefaultParentEntityPolicy.ts组合方式EntityPolicies提供allOf全部通过才放行逐个串行 enforce任一返回空则抛错与oneOf任一通过即可全部失败则抛不匹配任何已知策略两种组合子实现见 EntityPolicies.ts。七、在实践中的典型用法7.1 目录文件中的实体引用在catalog-info.yaml中编写spec时凡是引用其他实体的字段owner、system、providesApis等都应使用实体引用字符串apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: my-service namespace: default annotations: backstage.io/source-location: url:https://github.com/example/org/blob/main/catalog-info.yaml spec: type: service lifecycle: production owner: group:default/backend-team system: system:default/checkout providesApis: - api:default/my-api dependsOn: - resource:default/my-db7.2 在插件代码中解析引用import { parseEntityRef, stringifyEntityRef, getCompoundEntityRef, getEntitySourceLocation, } from backstage/catalog-model; const ref parseEntityRef(component:default/my-service, { defaultKind: Component, }); // { kind: component, namespace: default, name: my-service } const str stringifyEntityRef({ kind: Component, name: MyService }); // component:default/myservice自动小写并补齐命名空间 const loc getEntitySourceLocation(entity); // { type: url, target: https://... }7.3 组合自定义校验策略import { EntityPolicies, FieldFormatEntityPolicy, SchemaValidEntityPolicy, DefaultNamespaceEntityPolicy, makeValidator, } from backstage/catalog-model; const policy EntityPolicies.allOf([ new SchemaValidEntityPolicy(), new FieldFormatEntityPolicy(makeValidator()), new DefaultNamespaceEntityPolicy(), ]); await policy.enforce(entity);需要提示的是以上模式正是 catalog-backend 在 plugins/catalog-backend 中处理实体入库前校验的底层机制不同团队也可以在此之上替换makeValidator的覆盖项或自定义EntityPolicy以适配自己的命名规范。八、结论backstage/catalog-model用统一 Entity 结构 固定 Kind spec 实体引用寻址 分层校验策略四件事奠定了整个软件目录的格式基础。无论是阅读目录文件、开发 Catalog 插件、还是构建自定义 Kind 与校验规则理解本包公开 API 都是第一步。如需继续深入可进一步阅读实体类型与元数据定义packages/catalog-model/src/entity/Entity.ts实体引用解析实现packages/catalog-model/src/entity/ref.ts各内置 Kind 与关系注册packages/catalog-model/src/kinds校验与策略实现packages/catalog-model/src/validation、packages/catalog-model/src/entity/policiesJSON Schema 定义packages/catalog-model/src/schema完整的测试用例如 ref.test.ts、FieldFormatEntityPolicy.test.ts可验证上述所有行为【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表