Skip to content

🌐 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
  • 🌐 Underlying mechanism: Standard library net/http (ComposerClient) / third-party go-requests (Repository) initiates HTTPS requests, responses are JSON
  • 🔌 No PHP dependency: Completely decoupled from Composer CLI SDK, can be imported independently
  • Two-layer architecture: ComposerClient is the high-level business facade (20 methods), Repository is the lower-level HTTP call layer (statistics, listing, security advisories, index download)

Two-Layer Architecture

LayerTypePackageResponsibilitySuitable For
🌐 High-level facadeclient.ComposerClientpkg/clientWraps 20 Packagist endpoints, returns strongly-typed domain.* structuresMost business scenarios
🏗️ Lower-level HTTPrepository.Repositorypkg/repositoryDirectly interfaces with Packagist repository API, supports proxy, raw byte downloadNeed 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.

CategoryMethod CountKey MethodsSub-document
📦 Package Info5GetPackage, GetPackageWithV2Metadata, GetPackageDevVersions, GetPackageStats, GetPackageChangespackage-info
🔍 Search3SearchPackages, SearchPackagesByTags, SearchPackagesByTypesearch
📊 Statistics1GetStatisticsstatistics
🔒 Security Advisories3GetSecurityAdvisories, GetSecurityAdvisoriesForPackages, GetSecurityAdvisoriesSinceadvisories
📋 Package Listing5ListPackages, ListPackagesByVendor, ListPackagesByType, ListPackagesWithData, ListPopularPackageslisting
🛠️ Package Management3CreatePackage, EditPackage, UpdatePackage (requires API credentials)management
🪞 MirrorsOfficial mirror referencemirrors

Additionally, Repository Layer and Options documents describe the capabilities of lower-level pkg/repository.

Quick Examples

1. Get Complete Information for a Package

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("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

go
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

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. Lower-level Call with Proxy (Repository Layer)

go
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 with errors.Is/As.
  • 🔌 Optional Credentials: Only CreatePackage/EditPackage/UpdatePackage three write operations need WithAPICredentials(...), remaining read methods work anonymously.
  • ⚙️ Injectable Configuration: WithBaseURL, WithRepoURL allow pointing to self-hosted Packagist mirrors or Satis instances.

Next Steps

Released under the MIT License