Skip to content

🌐 Packagist API SDK 概览

pkg/clientpkg/repository 一起构成了 Composer Skills 项目中访问 Packagist.org纯 Go HTTP 客户端 SDK。它不依赖 PHP、不依赖本地 composer 二进制——所有数据通过 Packagist 的公开 HTTP/JSON API 直接获取,适合在 Go 服务、CI 流水线、监控脚本等任何无法或不需要安装 Composer 运行时的环境中使用。

模块定位

  • 📦 包路径
    • 高级门面:github.com/scagogogo/composer-skills/pkg/client
    • 底层 HTTP:github.com/scagogogo/composer-skills/pkg/repository
    • 领域模型:github.com/scagogogo/composer-skills/pkg/domain
  • 🌐 底层机制:标准库 net/httpComposerClient)/ 第三方 go-requestsRepository)发起 HTTPS 请求,响应为 JSON
  • 🔌 无 PHP 依赖:与 Composer CLI SDK 完全解耦,可单独引入
  • 两层架构ComposerClient 是面向业务的高级门面(20 个方法),Repository 是更底层的 HTTP 调用层(统计、列表、安全公告、索引下载)

两层架构

类型职责适合谁
🌐 高级门面client.ComposerClientpkg/client封装 20 个 Packagist 端点,返回强类型 domain.* 结构大多数业务场景
🏗️ 底层 HTTPrepository.Repositorypkg/repository直接对接 Packagist 仓库 API,支持代理、原始字节下载需要自定义端点 / 代理 / 索引文件下载

选哪一层?

90% 的场景用 client.NewComposerClient(...) 即可。只有当你需要:① 通过代理访问 Packagist;② 把整个包索引 list.json 落盘成文件;③ 拿到原始 JSON 字节自行解析——才需要直接用 repository 层。

20 个方法分类总览

ComposerClient 共暴露 20 个方法,按下表分 7 类。每类对应一份子文档。

分类方法数重点方法子文档
📦 包信息5GetPackageGetPackageWithV2MetadataGetPackageDevVersionsGetPackageStatsGetPackageChangespackage-info
🔍 搜索3SearchPackagesSearchPackagesByTagsSearchPackagesByTypesearch
📊 统计1GetStatisticsstatistics
🔒 安全公告3GetSecurityAdvisoriesGetSecurityAdvisoriesForPackagesGetSecurityAdvisoriesSinceadvisories
📋 包列表5ListPackagesListPackagesByVendorListPackagesByTypeListPackagesWithDataListPopularPackageslisting
🛠️ 包管理3CreatePackageEditPackageUpdatePackage(需 API 凭证)management
🪞 镜像官方镜像源参考mirrors

此外,Repository 层Options 文档介绍底层 pkg/repository 的能力。

快速示例

1. 获取一个包的完整信息

go
package main

import (
    "fmt"
    "log"
    "time"

    "github.com/scagogogo/composer-skills/pkg/client"
)

func main() {
    c := client.NewComposerClient(30 * time.Second)

    info, err := c.GetPackage("symfony/console")
    if err != nil {
        log.Fatalf("获取包信息失败: %v", err)
    }
    fmt.Printf("包名: %s\n", info.PackageName)
    fmt.Printf("描述: %s\n", info.Package.Description)
    fmt.Printf("总下载: %d\n", info.Package.Downloads.Total)
}

2. 搜索包

go
c := client.NewComposerClient(30 * time.Second)

res, err := c.SearchPackages("logger", 15, 1)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("共 %d 条结果\n", res.Total)
for _, r := range res.Results {
    fmt.Printf("- %s : %s\n", r.Name, r.Description)
}

3. 查指定包的安全公告

go
adv, err := c.GetSecurityAdvisoriesForPackages([]string{"symfony/http-foundation"})
if err != nil {
    log.Fatal(err)
}
for pkg, list := range adv.Advisories {
    for _, a := range list {
        fmt.Printf("[%s] %s (CVE: %s)\n", pkg, a.Title, a.Cve)
    }
}

4. 带代理的底层调用(Repository 层)

go
repo := repository.NewRepository(repository.Options{
    ServerUrl: "https://packagist.org",
    Proxy:     "http://127.0.0.1:7890",
})
stats, err := repo.Statistics(ctx)

设计约定

  • 🎯 返回值统一:高级门面方法要么返回 (*domain.XxxResponse, error)(强类型解析),要么返回 ([]byte, error)(原始 JSON,留给调用方自行解析,如 GetPackageWithV2Metadata)。
  • ⚠️ 错误包裹:HTTP 失败、状态码非 200、JSON 解析失败均以 fmt.Errorf("failed to ...: %w", err) 形式返回,可用 errors.Is/As 解包。
  • 🔌 凭证可选:只有 CreatePackage/EditPackage/UpdatePackage 三个写操作需要 WithAPICredentials(...),其余读取方法匿名即可。
  • ⚙️ 可注入配置WithBaseURLWithRepoURL 允许指向自建 Packagist 镜像或 Satis 实例。

下一步

基于 MIT 许可证发布