次の方法で共有


nuget.org に発行されたすべてのパッケージに対するクエリの実行

従来の OData V2 API に共通のクエリ パターンの 1 つは、nuget.org に発行されたすべてのパッケージを、そのパッケージの発行順に列挙するというものでした。 nuget.org に対するこの種のクエリに必要なシナリオは、次のように大きく異なります。

  • nuget.org を完全にレプリケートする
  • パッケージの新しいバージョンがリリースされたときに検出する
  • 使用しているパッケージに依存するパッケージを検索する

これを行う従来の方法は、一般的に、タイムスタンプによる OData パッケージ エンティティの並べ替え、および skiptop (ページ サイズ) パラメーターを使用する大規模な結果セットでのページングによって異なりました。 残念ながら、この方法には次のようないくつかの欠点があります。

  • 多くの場合、クエリはデータに対して変更順に実行されるため、パッケージが欠落する可能性がある
  • クエリが最適化されていないため、クエリの応答時間が遅くなる (最も最適化されたクエリとは、公式の NuGet クライアントの主要なシナリオをサポートするクエリのことです)
  • 非推奨とされた、ドキュメント化もされていない API の使用 (このようなクエリのサポートは将来的に保証されないことを意味します)
  • 正確な発生順に履歴を再生できない

このような理由から、以下のガイドに従うことで、より信頼性の高い将来性のある方法で前述のシナリオに対処できます。

概要

このガイドの中心となるのは、カタログと呼ばれる NuGet API のリソースです。 カタログは追加専用 API であり、呼び出し元は、nuget.org に対して追加、変更、および削除されたパッケージの完全な履歴を表示できます。nuget.org に発行されたパッケージのすべてに関心がある場合、またはその一部に関心がある場合でも、カタログは、時間が経過しても現在利用可能なパッケージのセットを最新の状態に保つ優れた方法です。

このガイドは簡単なチュートリアルであるため、カタログの詳細については、API 参照に関するドキュメントを参照してください。

次の手順は任意のプログラミング言語で実行できます。 完全な実行サンプルが必要な場合は、以下の C# のサンプルを参照してください。

それ以外の場合は、以下のガイドに従って、信頼性の高いカタログ リーダーをビルドします。

カーソルを初期化する

信頼性の高いカタログ リーダーをビルドする最初の手順は、カーソルの実装です。 カタログ カーソルの設計の詳細については、カタログ参照に関するドキュメントを参照してください。 要するに、カーソルは、カタログ内のイベントがどの時点まで処理されたかを示すものです。 カタログ内のイベントはあるパッケージの発行と他のパッケージの変更を示します。 これまでに (開始以降) NuGet に発行されたすべてのパッケージに関心がある場合は、カーソルを初期化してタイムスタンプが "最小値" (.NET の場合は DateTime.MinValue など) になるようにします。 これから発行されるパッケージのみに関心がある場合は、カーソル値を初期化する際に現在のタイムスタンプを使用します。

このガイドでは、タイムスタンプが 1 時間前になるようにカーソルを初期化します。 ここでは、単にそのタイムスタンプをメモリに保存します。

DateTime cursor = DateTime.UtcNow.AddHours(-1);

カタログ インデックス URL を判別する

NuGet API のすべてのリソース (エンドポイント) の場所は、サービス インデックスを使用して検出する必要があります。 このガイドでは nuget.org に焦点を当てているため、nuget.org のサービス インデックスを使用します。

GET https://api.nuget.org/v3/index.json

サービス ドキュメントは、nuget.org のすべてのリソースを含む JSON ドキュメントです。Catalog/3.0.0@type プロパティ値を持つリソースを検索します。 関連付けられている @idプロパティの値は、カタログ インデックス自体の URL です。

新しいカタログ リーフを見つける

前の手順で見つけた @id プロパティの値を使用して、カタログ インデックスをダウンロードします。

GET https://api.nuget.org/v3/catalog0/index.json

カタログ インデックスを逆シリアル化します。 すべてのカタログ ページ オブジェクトを、現在のカーソル値以下の commitTimeStamp でフィルタリングします。

残りのカタログ ページごとに、@id プロパティを使用して完全なドキュメントをダウンロードします。

GET https://api.nuget.org/v3/catalog0/page2926.json

カタログ ページを逆シリアル化します。 すべてのカタログ リーフ オブジェクトを、現在のカーソル値以下の commitTimeStamp でフィルタリングします。

フィルタリングされなかったカタログ ページをすべてダウンロードした後、カーソルのタイムスタンプから今までに公開、リスト解除、リスト、または削除されたパッケージを表す一連のカタログ リーフ オブジェクトが示されます。

カタログ リーフを処理する

この時点で、カタログ項目に対して必要なカスタム処理を実行することができます。 必要なものがパッケージの ID とバージョンのみである場合は、ページで検出されたカタログ項目オブジェクトの nuget:id および nuget:version プロパティを調べることができます。 必ず、@type プロパティを調べ、カタログ項目が既存のパッケージと削除されたパッケージのどちらに関するものであるかを確認してください。

パッケージに関するメタデータ (説明、依存関係、.nupkg サイズなど) に興味がある場合は、@id プロパティを使用してカタログ リーフ ドキュメントをフェッチできます。

GET https://api.nuget.org/v3/catalog0/data/2015.02.01.11.18.40/windowsazure.storage.1.0.0.json

このドキュメントには、パッケージ メタデータ リソースなどに含まれるすべてのメタデータが示されます。

この手順では、カスタム ロジックを実装します。 このガイドの他の手順は、カタログ リーフでの実行内容に関係なく、ほとんど同じ方法で行われます。

.nupkg のダウンロード

カタログで検出されたパッケージ用の .nupkg をダウンロードしたい場合は、パッケージ コンテンツ リソースを使用できます。 ただし、パッケージがカタログで検出されてから、パッケージ コンテンツ リソースで使用できるようになるまで短い遅延が発生することに注意してください。 したがって、カタログで検出されたパッケージの .nupkg をダウンロードしようとしたときに 404 Not Found が発生した場合は、しばらくしてから再試行するだけです。 この遅延の修正については、GitHub の問題 NuGet/NuGetGallery#3455 で追跡されています。

カーソルを先に進める

カタログ項目を正しく処理したら、保存する新しいカーソル値を判別する必要があります。 これを行うには、処理したすべてのカタログ項目の最大 (最新) commitTimeStamp を検索します。 これが新しいカーソル値になります。 データベース、ファイル システム、または BLOB ストレージなどのいくつかの固定ストアに保存します。 カタログ項目をさらに取得する場合は、この固定ストアのカーソル値を初期化して、最初の手順から開始するだけです。

アプリケーションが例外やフォールトをスローする場合は、カーソルを先に進めないでください。 カーソルを先に進めるということは、カーソルの前のカタログ項目を再度処理する必要がないことを意味します。

なんらかの理由で、カタログ リーフの処理方法にバグが発生した場合は、その時点までカーソルを戻すだけで、コードで以前のカタログ項目を再処理することができます。

C# サンプル コード

カタログは HTTP 経由で使用可能な一連の JSON ドキュメントであるため、HTTP クライアントと JSON デシリアライザーを持つ任意のプログラミング言語を使用して対話することができます。

C# のサンプルは、NuGet/Sample リポジトリで入手可能です。

git clone https://github.com/NuGet/Samples.git

カタログ SDK

カタログを使用する最も簡単な方法は、プレリリースの .NET カタログ SDK パッケージ NuGet.Protocol.Catalog を使用することです。これは、次の NuGet パッケージ ソース URL を使用して、Azure Artifacts で利用できます: https://pkgs.dev.azure.com/dnceng/public/_packaging/nuget-build/nuget/v3/index.json

このパッケージを、netstandard1.3 以上 (.NET Framework 4.6 など) と互換性のあるプロジェクトにインストールすることができます。

このパッケージを使用するサンプルは、GitHub の NuGet.Protocol.Catalog.Sample プロジェクトで入手できます。

サンプル出力

2017-11-10T22:16:44.8689025+00:00: Found package details leaf for xSkrape.APIWrapper.REST 1.0.2.
2017-11-10T22:16:54.6972769+00:00: Found package details leaf for xSkrape.APIWrapper.REST 1.0.1.
2017-11-10T22:19:20.6385542+00:00: Found package details leaf for Platform.EnUnity 1.0.8.
...
2017-11-10T23:05:04.9695890+00:00: Found package details leaf for xSkrape.APIWrapper.Base 1.0.1.
2017-11-10T23:05:04.9695890+00:00: Found package details leaf for xSkrape.APIWrapper.Base 1.0.2.
2017-11-10T23:07:23.1303569+00:00: Found package details leaf for VeiculoX.Model 0.0.15.
Processing the catalog leafs failed. Retrying.
fail: NuGet.Protocol.Catalog.LoggerCatalogLeafProcessor[0]
      10 catalog commits have been processed. We will now simulate a failure.
warn: NuGet.Protocol.Catalog.CatalogProcessor[0]
      Failed to process leaf https://api.nuget.org/v3/catalog0/data/2017.11.10.23.07.23/veiculox.model.0.0.15.json (VeiculoX.Model 0.0.15, PackageDetails).
warn: NuGet.Protocol.Catalog.CatalogProcessor[0]
      13 out of 59 leaves were left incomplete due to a processing failure.
warn: NuGet.Protocol.Catalog.CatalogProcessor[0]
      1 out of 1 pages were left incomplete due to a processing failure.
2017-11-10T23:07:23.1303569+00:00: Found package details leaf for VeiculoX.Model 0.0.15.
2017-11-10T23:07:33.0212446+00:00: Found package details leaf for VeiculoX.Model 0.0.14.
2017-11-10T23:07:41.6621837+00:00: Found package details leaf for VeiculoX.Model 0.0.13.
2017-11-10T23:09:58.5728614+00:00: Found package details leaf for CreaSoft.Composition.Web.Extensions 1.1.0.
2017-11-10T23:09:58.5728614+00:00: Found package details leaf for DarkXaHTeP.Extensions.Configuration.Consul 0.0.4.
2017-11-10T23:09:58.5728614+00:00: Found package details leaf for xSkrape.APIWrapper.REST.Sample 1.0.3.
2017-11-10T23:10:09.0574930+00:00: Found package details leaf for Microsoft.VisualStudio.Imaging 15.4.27004.
2017-11-10T23:10:09.0574930+00:00: Found package details leaf for Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime 14.3.25407.
2017-11-10T23:10:09.0574930+00:00: Found package details leaf for Microsoft.VisualStudio.Language.Intellisense 15.4.27004.
2017-11-10T23:10:09.0574930+00:00: Found package details leaf for Microsoft.VisualStudio.Language.StandardClassification 15.4.27004.
2017-11-10T23:10:09.0574930+00:00: Found package details leaf for Microsoft.VisualStudio.ManagedInterfaces 8.0.50727.
2017-11-10T23:10:09.0574930+00:00: Found package details leaf for xSkrape.APIWrapper.REST.Sample 1.0.2.
2017-11-10T23:10:09.0574930+00:00: Found package details leaf for xSkrape.APIWrapper.REST.Sample 1.0.3.

最小サンプル

カタログとの対話を詳細に示す、いくつかの依存関係を含む例については、CatalogReaderExample サンプル プロジェクトを参照してください。 プロジェクトは netcoreapp2.0 をターゲットとし、NuGet.Protocol 4.4.0 (サービス インデックスを解決する場合) および Newtonsoft.Json 9.0.1 (JSON シリアル化解除の場合) に依存します。

コードの主なロジックは Program.cs ファイルに表示されます。

サンプル出力

No cursor found. Defaulting to 11/2/2017 9:41:28 PM.
Fetched catalog index https://api.nuget.org/v3/catalog0/index.json.
Fetched catalog page https://api.nuget.org/v3/catalog0/page2935.json.
Processing 69 catalog leaves.
11/2/2017 9:32:35 PM: DotVVM.Compiler.Light 1.1.7 (type is nuget:PackageDetails)
11/2/2017 9:32:35 PM: Momentum.Pm.Api 5.12.181-beta (type is nuget:PackageDetails)
11/2/2017 9:32:44 PM: Momentum.Pm.PortalApi 5.12.181-beta (type is nuget:PackageDetails)
11/2/2017 9:35:14 PM: Genesys.Extensions.Standard 3.17.11.40 (type is nuget:PackageDetails)
11/2/2017 9:35:14 PM: Genesys.Extensions.Core 3.17.11.40 (type is nuget:PackageDetails)
11/2/2017 9:35:14 PM: Halforbit.DataStores.FileStores.Serialization.Bond 1.0.4 (type is nuget:PackageDetails)
11/2/2017 9:35:14 PM: Halforbit.DataStores.FileStores.AmazonS3 1.0.4 (type is nuget:PackageDetails)
11/2/2017 9:35:14 PM: Halforbit.DataStores.DocumentStores.DocumentDb 1.0.6 (type is nuget:PackageDetails)
11/2/2017 9:35:14 PM: Halforbit.DataStores.FileStores.BlobStorage 1.0.5 (type is nuget:PackageDetails)
...
11/2/2017 10:23:54 PM: Cake.GitPackager 0.1.2 (type is nuget:PackageDetails)
11/2/2017 10:23:54 PM: UtilPack.NuGet 2.0.0 (type is nuget:PackageDetails)
11/2/2017 10:23:54 PM: UtilPack.NuGet.AssemblyLoading 2.0.0 (type is nuget:PackageDetails)
11/2/2017 10:26:26 PM: UtilPack.NuGet.Deployment 2.0.0 (type is nuget:PackageDetails)
11/2/2017 10:26:26 PM: UtilPack.NuGet.Common.MSBuild 2.0.0 (type is nuget:PackageDetails)
11/2/2017 10:26:36 PM: InstaClient 1.0.2 (type is nuget:PackageDetails)
11/2/2017 10:26:36 PM: SecureStrConvertor.VARUN_RUSIYA 1.0.0.5 (type is nuget:PackageDetails)
Writing cursor value: 11/2/2017 10:26:36 PM.