> Source: https://www.ymotongpoo.com/works/goblog-ja/pkgsite-api/


# pkg.go.dev APIの紹介

[Introducing the pkg.go.dev API](https://go.dev/blog/pkgsite-api) by Ethan Lee, Hana Kim, and Jonathan Amsterdam

[pkg.go.dev](https://pkg.go.dev) は登場以来、パッケージのドキュメントと発見のためのGoコミュニティの主要なリソースとしての地位を確立してきました。
私たちは当初、ユーザー向けに包括的で高いアクセシビリティを備えたWebインターフェースを作ることを優先していましたが、
プログラムからのアクセスに対する需要はますます明らかになってきました。ツールやIDEの統合、自動化されたワークフローを構築する
開発者たちは、これまでこのデータにアクセスするために、Webスクレイピングのような脆弱な回避策に頼らざるを得ませんでした。
このような変化していくニーズによりよく応えるために、私たちは今、コミュニティが必要としている情報への堅牢で直接的な
アクセスを提供するようプラットフォームを拡張しています。

本日、公開されているGoモジュールに関するメタデータを問い合わせるためのサービスインターフェースである、公式の
[pkg.go.dev API](https://pkg.go.dev/api) を発表できることを嬉しく思います。この公開は、長年にわたるコミュニティからの
フィードバックに直接応えるものです。AIを活用したコーディングの台頭により、形式化されたインターフェースの必要性は
一段と切実なものになっています。ツールは今や、Goのエコシステムについてより高い精度で推論するために必要な、
具体的で忠実度の高いコンテキストにアクセスできるようになります。

## サービスインターフェース

安定性と効率的なキャッシュのために設計されたこのAPIは、ステートレスでGETのみのアーキテクチャを採用しています。
主要なエンドポイントは現在 `/v1beta` パス以下でホストされています。コミュニティからのフィードバックを受け、
安定性が確認された後、正式な `v1` リリースへと移行する予定です。

すべてのエンドポイント、クエリパラメータ、レスポンスの形式についての完全なインタラクティブなリファレンスは、
[pkg.go.dev/api の仕様](https://pkg.go.dev/api) を参照してください。機械可読なAPI仕様は
[OpenAPI仕様](https://pkg.go.dev/v1beta/openapi.yaml) としても直接公開されています。

### 主要なエンドポイント

| エンドポイント | 説明 |
|---|---|
| `/v1beta/package/{path}` | `{path}` にあるパッケージの情報。 |
| `/v1beta/module/{path}` | `{path}` にあるモジュールの情報。 |
| `/v1beta/versions/{path}` | `{path}` にあるモジュールのバージョン一覧。 |
| `/v1beta/packages/{path}` | `{path}` にあるモジュールが持つパッケージの情報。 |
| `/v1beta/search?q={query}` | 指定したクエリに対する検索結果。 |
| `/v1beta/symbols/{path}` | `{path}` にあるパッケージが宣言するシンボルの一覧。 |
| `/v1beta/imported-by/{path}` | `{path}` にあるパッケージをインポートしているパッケージのパス一覧。 |
| `/v1beta/vulns/{path}` | `{path}` にあるモジュールまたはパッケージの脆弱性情報。 |

このAPIの設計原則の一つは「利便性より正確性」です。参考までに、 `go mod tidy` がメインモジュールの
既存の依存関係によって提供されていないパッケージのインポートに遭遇すると、どのモジュールが必要かを判断するために
「最も長いモジュールパス」規則を適用します。（複数のモジュールが同じパッケージを提供できるという事実こそが、
既存のプログラムを壊すことなく後からサブモジュールを切り出すことを可能にしています。） [pkg.go.dev](https://pkg.go.dev)
のWebインターフェースは、あるパッケージパスに対してどのパッケージを表示するかを選ぶ際に、これと同様の慣習に従っています。
対照的に、 [pkg.go.dev](https://pkg.go.dev) APIはモジュールを曖昧さなく指定することを要求します。パッケージパスが
複数のモジュールに存在するために曖昧である場合、APIは候補のリストを返し、クライアントにより具体的な指定を求める
エラーを報告します。

例えば、 `example.com/a/b/c` としてインポートされるパッケージは、モジュール `example.com/a` あるいは
`example.com/a/b` のどちらからも提供されうるでしょう。 [pkg.go.dev](https://pkg.go.dev) のWebインターフェースは
自動的に「最も長いモジュールパス」（ `example.com/a/b` ）を解決しますが、APIに問い合わせるクライアントは、
曖昧な解決によるエラーを避けるために明示的にモジュールを指定しなければなりません。

### バージョンの指定

パッケージ、モジュール、あるいはシンボルの情報を取得するエンドポイントでは、任意の `version` クエリパラメータを
使って希望するバージョンを指定できます。このパラメータを省略した場合、APIはデフォルトでモジュールあるいはパッケージの
最新バージョンの情報を返します。このパラメータは次のものをサポートしています。

* **セマンティックバージョン：** 特定のリリースタグのデータを取得します（例： `?version=v1.2.3` や `?version=v0.6.0` ）。
* **ブランチ名：** デフォルトの開発ブランチ、具体的には `master` あるいは `main` を参照します（例： `?version=master` ）。
  APIは自動的にそのブランチを対応する疑似バージョンに解決します。任意のカスタムなブランチ名はサポートされていない点に
  注意してください。

`version` パラメータが省略された場合、APIはデフォルトでパッケージあるいはモジュールの最新のタグ付きバージョンに対して
リクエストを解決します。

### 生のAPIリクエストの例

特定のパッケージの構造化されたメタデータを直接取得する例です（整形には `jq` を使用しています）。

```console
$ curl https://pkg.go.dev/v1beta/package/github.com/google/go-cmp/cmp | jq .
{
  "modulePath": "github.com/google/go-cmp",
  "version": "v0.7.0",
  "isLatest": true,
  "isStandardLibrary": false,
  "goos": "all",
  "goarch": "all",
  "path": "github.com/google/go-cmp/cmp",
  "name": "cmp",
  "synopsis": "Package cmp determines equality of values.",
  "isRedistributable": true
}
```

特定のブランチのバージョン（ `master` など）を問い合わせて、それが対応する疑似バージョンへ自動的に解決される様子を
見てみましょう。

```console
$ curl -s "https://pkg.go.dev/v1beta/package/github.com/google/go-cmp/cmp?version=master" | jq '{path, version}'
{
  "path": "github.com/google/go-cmp/cmp",
  "version": "v0.7.1-0.20260310220054-34c9473539b8"
}
```

## pkgsite-cliリファレンス実装

APIとの対話の仕方を示すために、リファレンスとなるクライアント実装
[pkgsite-cli](https://github.com/golang/pkgsite/tree/master/cmd/internal/pkgsite-cli) を提供しています。
この実装は、独自の統合を構築しようとする開発者にとって、ターミナルから直接データを扱う方法を示す実践的な例になります。
このコマンドのインターフェースと挙動は、APIの発展に伴って変わりうることに注意してください。

始めるには、次のコマンドをインストールします。

```bash
$ go install golang.org/x/pkgsite/cmd/internal/pkgsite-cli@latest
```

パッケージを検索するには次のようにします。

```
$ pkgsite-cli search "uuid"
github.com/google/uuid
  Module:   github.com/google/uuid@v1.6.0
  Synopsis: Package uuid generates and inspects UUIDs.
... more
```

特定のパッケージを調べるには次のようにします。

```
$ pkgsite-cli package github.com/google/go-cmp/cmp
github.com/google/go-cmp/cmp
  Name:      cmp
  Module:    github.com/google/go-cmp
  Version:   v0.7.0 (latest)
  Synopsis:  Package cmp determines equality of values.
```

あるパッケージをどのパッケージがインポートしているかを見るには次のようにします。

```
$ pkgsite-cli package --imported-by github.com/google/go-cmp/cmp
github.com/google/go-cmp/cmp
  Name:     cmp
  Module:   github.com/google/go-cmp
  Version:  v0.7.0 (latest)
  Synopsis: Package cmp determines equality of values.

Imported by:
  cloud.google.com/go/internal/testutil
  cuelang.org/go/internal/cuetxtar
  chainguard.dev/apko/pkg/build/types
  ... more
```

パッケージが宣言するシンボルの一覧を見るには次のようにします。

```
$ pkgsite-cli package --symbols github.com/google/go-cmp/cmp
github.com/google/go-cmp/cmp
  Name:     cmp
  Module:   github.com/google/go-cmp
  Version:  v0.7.0 (latest)
  Synopsis: Package cmp determines equality of values.

Symbols:
  type Indirect struct{}
  type MapIndex struct{}
  type Option interface{}
  ... more
```

モジュールのバージョン一覧を見るには次のようにします。

```
$ pkgsite-cli module -versions github.com/google/go-cmp
github.com/google/go-cmp
  Version:          v0.7.0 (latest)
  Repository:       https://github.com/google/go-cmp
  Has go.mod:       yes
  Redistributable:  yes

Versions:
  v0.7.0
  v0.6.0
  v0.5.9
  ... more
```

モジュールのバージョンとパッケージの両方の一覧を見るには次のようにします。

```
$ pkgsite-cli module -packages -versions github.com/google/go-cmp
github.com/google/go-cmp
  Version:          v0.7.0 (latest)
  Repository:       https://github.com/google/go-cmp
  Has go.mod:       yes
  Redistributable:  yes

Versions:
  v0.7.0
  v0.6.0
  v0.5.9
  ... more

Packages:
  github.com/google/go-cmp/cmp             Package cmp determines equality of values.
  github.com/google/go-cmp/cmp/cmpopts     Package cmpopts provides common options for the cmp package.
  ... more
```

このコマンドはページネーションと整形を処理してくれるので、スクリプトや手動での調査に必要なデータに
集中できます。詳しくは、 [pkgsite-cliのドキュメント](https://pkg.go.dev/golang.org/x/pkgsite/cmd/internal/pkgsite-cli)
を参照してください。

## 安定性とこれから

以上で [pkg.go.dev](https://pkg.go.dev) APIの簡単な紹介を終わります。今後もインターフェースの機能を拡張していく
予定ですが、既存の統合がそのまま問題なく動作し続けるよう、後方互換性の維持に取り組んでいきます。（ `pkgsite-cli`
リファレンスクライアントのコマンドラインインターフェース自体は、まだ安定していないことに注意してください。）
[イシュートラッカー](https://github.com/golang/go/issues) を通じたフィードバックをお待ちしていますし、
コミュニティが構築する新しいツールやワークフローを楽しみにしています。

By Ethan Lee, Hana Kim, and Jonathan Amsterdam

