Skip to content

🔌 客户端 ComposerClient

pkg/client.ComposerClient 是 Packagist API SDK 的高级门面。它把 Packagist 的公开 HTTP/JSON 端点封装成 20 个类型安全的 Go 方法,返回值直接是 pkg/domain 下的强类型结构,调用方无需自行处理 HTTP 请求、状态码判断与 JSON 反序列化。

纯 Go,无需 PHP

ComposerClient 只依赖 Go 标准库 net/http,不调用本地 composer 二进制,也不需要 PHP 运行时。可独立于 Composer CLI SDK 单独使用。

何时使用

  • 🌐 你的服务在 Go 中需要查询 Packagist 上的包元数据、下载统计或安全公告。
  • 🛠️ CI/CD 流水线里用 Go 脚本检查依赖的漏洞或下载量,不想为了一个 HTTP 调用再装 PHP。
  • 📊 需要把 Packagist 数据落库做长期趋势分析,ComposerClient 给你强类型结构直接入库。
  • 🔌 需要指向自建镜像 / Satis 实例:用 WithBaseURL / WithRepoURL 覆盖默认地址。

创建客户端

NewComposerClient

go
func NewComposerClient(timeout time.Duration, options ...ComposerClientOption) *ComposerClient
参数类型说明
timeouttime.DurationHTTP 客户端整体超时,传给 http.Client.Timeout
options...ComposerClientOption可选配置函数,按需覆盖默认 base URL、repo URL、API 凭证

默认值

字段默认值含义
baseURLhttps://packagist.org业务 API 端点(包信息、搜索、统计、列表、管理)
repoURLhttps://repo.packagist.org仓库元数据端点(V2 元数据 p2/...、dev 版本)
username / apiToken仅写操作需要,见 WithAPICredentials

示例

go
package main

import (
    "fmt"
    "log"
    "time"

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

func main() {
    // 最简:30 秒超时,匿名访问官方 Packagist
    c := client.NewComposerClient(30 * time.Second)

    stats, err := c.GetStatistics()
    if err != nil {
        log.Fatalf("获取统计失败: %v", err)
    }
    fmt.Printf("Packagist 共有 %d 个包\n", stats.Totals.Packages)
}

配置选项

所有选项都是 ComposerClientOption 函数,按需传入 NewComposerClient

WithBaseURL

go
func WithBaseURL(baseURL string) ComposerClientOption
参数类型说明
baseURLstring业务 API 基础 URL,覆盖默认 https://packagist.org

覆盖后,GetPackageGetStatisticsSearchPackagesListPackages*GetSecurityAdvisories*CreatePackage 等方法都会拼接这个前缀。指向自建 Packagist 镜像或私有 Packagist 实例时使用。

go
c := client.NewComposerClient(
    30*time.Second,
    client.WithBaseURL("https://packagist.mycompany.com"),
)

WithRepoURL

go
func WithRepoURL(repoURL string) ComposerClientOption
参数类型说明
repoURLstring仓库元数据基础 URL,覆盖默认 https://repo.packagist.org

仅影响 GetPackageWithV2MetadataGetPackageDevVersions 两个方法(它们走 p2/... 端点)。

go
c := client.NewComposerClient(
    30*time.Second,
    client.WithRepoURL("https://repo.packagist.mycompany.com"),
)

WithAPICredentials

go
func WithAPICredentials(username, apiToken string) ComposerClientOption
参数类型说明
usernamestringPackagist 账号用户名
apiTokenstringPackagist 个人 API token(在 packagist.org 个人页生成)

凭证安全

usernameapiToken 会作为 URL 查询参数拼接到请求 URL 中(Packagist API 的设计)。请勿在不安全的日志中打印完整请求 URL。建议从环境变量或密钥管理服务读取,不要硬编码进源码。

只有三个写操作需要凭证,未配置时调用会直接返回错误:

go
c := client.NewComposerClient(
    30*time.Second,
    client.WithAPICredentials(
        os.Getenv("PACKAGIST_USERNAME"),
        os.Getenv("PACKAGIST_API_TOKEN"),
    ),
)

完整方法清单

下表列出 ComposerClient 的全部 20 个方法。详细签名、参数与示例见对应子文档。

方法签名概要返回类型子文档
📦 GetPackage(packageName string)(*domain.ComposerPackageInfo, error)package-info
📦 GetPackageWithV2Metadata(packageName string)([]byte, error)package-info
📦 GetPackageDevVersions(packageName string)([]byte, error)package-info
📦 GetPackageStats(packageName string)(*domain.PackageStatsResponse, error)package-info
📦 GetPackageChanges(ctx context.Context, since int64)(*domain.ChangeTrackingResponse, error)package-info
🔍 SearchPackages(query string, perPage, page int)(*domain.SearchResponse, error)search
🔍 SearchPackagesByTags(tags []string, perPage, page int)(*domain.SearchResponse, error)search
🔍 SearchPackagesByType(query, packageType string, perPage, page int)(*domain.SearchResponse, error)search
📊 GetStatistics()(*domain.StatisticsResponse, error)statistics
🔒 GetSecurityAdvisories()(*domain.AdvisoriesResponse, error)advisories
🔒 GetSecurityAdvisoriesForPackages(packageNames []string)(*domain.AdvisoriesResponse, error)advisories
🔒 GetSecurityAdvisoriesSince(updatedSince time.Time)(*domain.AdvisoriesResponse, error)advisories
📋 ListPackages()(*domain.PackageListResponse, error)listing
📋 ListPackagesByVendor(vendor string)(*domain.PackageListResponse, error)listing
📋 ListPackagesByType(packageType string)(*domain.PackageListResponse, error)listing
📋 ListPackagesWithData(fields []string)(*domain.PackageListWithDataResponse, error)listing
📋 ListPopularPackages(perPage int)(*domain.PopularPackagesResponse, error)listing
🛠️ CreatePackage(ctx, *domain.PackageCreateRequest)(*domain.PackageCreateResponse, error)management
🛠️ EditPackage(ctx, packageName, *domain.PackageEditRequest)(*domain.PackageEditResponse, error)management
🛠️ UpdatePackage(ctx, *domain.PackageUpdateRequest)(*domain.PackageUpdateResponse, error)management

进阶

超时设置

NewComposerClient 的第一个参数 timeout 直接赋给 http.Client.Timeout,覆盖所有阶段(连接、TLS 握手、读 body)。生产环境建议设 30s–60s;下载大型索引(ListPackagesWithData 返回量大)时可适当调大,或改用底层 Repository 层DownloadIndexToFile 落盘后流式处理。

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

注意

ComposerClient 不支持自定义 http.Transport(如需自定义重试、连接池、TLS 配置,请改用底层 repository.Repository,它通过 go-requests 支持 Proxy 等设置项)。

组合多个选项

go
c := client.NewComposerClient(
    45*time.Second,
    client.WithBaseURL("https://packagist.mycompany.com"),
    client.WithRepoURL("https://repo.packagist.mycompany.com"),
    client.WithAPICredentials(user, token),
)

🔗 相关

基于 MIT 许可证发布