🌐 Packagist API SDK Overview
pkg/client and pkg/repository together form the pure Go HTTP client SDK for accessing Packagist.org in the Composer Skills project. It does not depend on PHP or local composer binary — all data is fetched directly via Packagist's public HTTP/JSON APIs, suitable for use in Go services, CI pipelines, monitoring scripts, and any environment where Composer runtime cannot or need not be installed.
Module Positioning
- 📦 Package paths:
- High-level facade:
github.com/scagogogo/composer-skills/pkg/client - Lower-level HTTP:
github.com/scagogogo/composer-skills/pkg/repository - Domain models:
github.com/scagogogo/composer-skills/pkg/domain
- High-level facade:
- 🌐 Underlying mechanism: Standard library
net/http(ComposerClient) / third-partygo-requests(Repository) initiates HTTPS requests, responses are JSON - 🔌 No PHP dependency: Completely decoupled from Composer CLI SDK, can be imported independently
- ⚡ Two-layer architecture:
ComposerClientis the high-level business facade (20 methods),Repositoryis the lower-level HTTP call layer (statistics, listing, security advisories, index download)
Two-Layer Architecture
| Layer | Type | Package | Responsibility | Suitable For |
|---|---|---|---|---|
| 🌐 High-level facade | client.ComposerClient | pkg/client | Wraps 20 Packagist endpoints, returns strongly-typed domain.* structures | Most business scenarios |
| 🏗️ Lower-level HTTP | repository.Repository | pkg/repository | Directly interfaces with Packagist repository API, supports proxy, raw byte download | Need custom endpoints / proxy / index file download |
Which Layer to Choose?
90% of scenarios can use client.NewComposerClient(...). Only when you need: ① Access Packagist via proxy; ② Save entire package index list.json to file; ③ Get raw JSON bytes to parse yourself — then use the repository layer directly.
20 Methods Classification Overview
ComposerClient exposes 20 methods, classified into 7 categories as shown below. Each category has a sub-document.
| Category | Method Count | Key Methods | Sub-document |
|---|---|---|---|
| 📦 Package Info | 5 | GetPackage, GetPackageWithV2Metadata, GetPackageDevVersions, GetPackageStats, GetPackageChanges | package-info |
| 🔍 Search | 3 | SearchPackages, SearchPackagesByTags, SearchPackagesByType | search |
| 📊 Statistics | 1 | GetStatistics | statistics |
| 🔒 Security Advisories | 3 | GetSecurityAdvisories, GetSecurityAdvisoriesForPackages, GetSecurityAdvisoriesSince | advisories |
| 📋 Package Listing | 5 | ListPackages, ListPackagesByVendor, ListPackagesByType, ListPackagesWithData, ListPopularPackages | listing |
| 🛠️ Package Management | 3 | CreatePackage, EditPackage, UpdatePackage (requires API credentials) | management |
| 🪞 Mirrors | — | Official mirror reference | mirrors |
Additionally, Repository Layer and Options documents describe the capabilities of lower-level pkg/repository.
Quick Examples
1. Get Complete Information for a Package
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("Failed to get package info: %v", err)
}
fmt.Printf("Package name: %s\n", info.PackageName)
fmt.Printf("Description: %s\n", info.Package.Description)
fmt.Printf("Total downloads: %d\n", info.Package.Downloads.Total)
}2. Search Packages
c := client.NewComposerClient(30 * time.Second)
res, err := c.SearchPackages("logger", 15, 1)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Total %d results\n", res.Total)
for _, r := range res.Results {
fmt.Printf("- %s : %s\n", r.Name, r.Description)
}3. Query Security Advisories for Specific Packages
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. Lower-level Call with Proxy (Repository Layer)
repo := repository.NewRepository(repository.Options{
ServerUrl: "https://packagist.org",
Proxy: "http://127.0.0.1:7890",
})
stats, err := repo.Statistics(ctx)Design Conventions
- 🎯 Unified Return Values: High-level facade methods either return
(*domain.XxxResponse, error)(strongly-typed parsing) or([]byte, error)(raw JSON, left for caller to parse, e.g.,GetPackageWithV2Metadata). - ⚠️ Error Wrapping: HTTP failure, non-200 status code, JSON parsing failure all return as
fmt.Errorf("failed to ...: %w", err), can be unwrapped witherrors.Is/As. - 🔌 Optional Credentials: Only
CreatePackage/EditPackage/UpdatePackagethree write operations needWithAPICredentials(...), remaining read methods work anonymously. - ⚙️ Injectable Configuration:
WithBaseURL,WithRepoURLallow pointing to self-hosted Packagist mirrors or Satis instances.
Next Steps
- 🔌 First read ComposerClient: Understand how to create client, set timeout and credentials.
- 📦 Then read Package Info: Master
GetPackageseries methods. - 🔒 Security-related see Security Advisories; statistics see Statistics.
- 🏗️ Need proxy or index file download see Repository Layer and Options.