基于 Harbor API v2.0 的镜像仓库查询代理实践

需求

管理后台的镜像仓库页面需要展示各项目的镜像列表和标签。Harbor 的凭证不能暴露给浏览器,前端也不适合直接处理 Harbor 的分页协议,于是在后端加了一层代理服务。

方案

后端新增 RegistryService,通过 Basic Auth 调用 Harbor API v2.0,前端只与自家 API 交互。这样做带来三个额外好处:分页在服务端聚合完成、错误信息统一格式、镜像地址规范化。

关键接口

分页处理

Harbor 使用 page 和 page_size 分页,总数在响应头 X-Total-Count 中返回。仓库数量多时必须循环拉取并在服务端聚合,否则前端拿到的永远只是第一页。

镜像地址规范化

统一为 registry/project/image:tag 格式,页面展示、复制按钮、拉取命令都基于同一格式拼接。之前各处各写各的,出现过展示名和实际拉取地址不一致的低级问题。

代码片段

public List<ImageTag> listTags(String project, String repo) {
    String url = harborBase + "/projects/" + project
        + "/repositories/" + urlEncode(repo)
        + "/artifacts?with_tag=true";
    return restClient.get()
        .header(HttpHeaders.AUTHORIZATION, basicAuth())
        .retrieve()
        .body(ArtifactPage.class)
        .getTags();
}

配套策略

镜像保留策略设定为每个镜像仓库只保留最近 3 个版本,清理由 CI 流水线定时执行。页面上明确提示该策略,避免用户以为历史版本随时可以拉取。

代理层的价值不只是隐藏凭证——分页聚合、错误统一、地址规范化,这些「脏活」放在服务端,前端才能保持简单。
← 上一篇:React i18n 排查 下一篇:App Keeper 设计思路 →