Udostępnij za pośrednictwem


Zapytanie o wszystkie pakiety opublikowane w nuget.org

Jednym z typowych wzorców zapytań w starszym interfejsie API OData w wersji 2 było wyliczanie wszystkich pakietów publikowanych w nuget.org uporządkowanych według daty opublikowania pakietu. Scenariusze wymagające tego rodzaju zapytań względem nuget.org różnią się znacznie:

  • Replikowanie nuget.org całkowicie
  • Wykrywanie, kiedy pakiety mają wydane nowe wersje
  • Znajdowanie pakietów, które zależą od pakietu

Starszy sposób wykonywania tej czynności zwykle zależy od sortowania jednostki pakietu OData przez sygnaturę czasową i stronicowanie w masowym zestawie wyników przy użyciu skip parametrów i top (rozmiar strony). Niestety, takie podejście ma pewne wady:

  • Możliwość braku pakietów, ponieważ zapytania są wykonywane na danych, które często zmieniają kolejność
  • Czas odpowiedzi wolnych zapytań, ponieważ zapytania nie są zoptymalizowane (najbardziej zoptymalizowane zapytania to te, które obsługują scenariusz główny dla oficjalnego klienta NuGet)
  • Korzystanie z przestarzałego i nieudokumentowanego interfejsu API, co oznacza, że obsługa takich zapytań w przyszłości nie jest gwarantowana
  • Niezdolność do odtwarzania historii w dokładnej kolejności, jaką się okazało

Z tego powodu można postępować zgodnie z poniższym przewodnikiem, aby rozwiązać wyżej wymienione scenariusze w bardziej niezawodny i niezawodny sposób na przyszłość.

Omówienie

W centrum tego przewodnika znajduje się zasób interfejsu API NuGet o nazwie wykaz. Wykaz jest interfejsem API tylko do dołączania, który umożliwia wywołującym wyświetlanie pełnej historii pakietów dodanych do, zmodyfikowanych i usuniętych z nuget.org. Jeśli interesuje Cię wszystkie lub nawet podzbiór pakietów opublikowanych w celu nuget.org, katalog jest doskonałym sposobem na aktualizowanie zestawu aktualnie dostępnych pakietów w miarę upływu czasu.

Ten przewodnik ma być przewodnikiem wysokiego poziomu, ale jeśli interesuje Cię szczegółowe szczegóły wykazu, zapoznaj się z dokumentem referencyjnym interfejsu API.

Poniższe kroki można zaimplementować w dowolnym wybranym języku programowania. Jeśli chcesz skorzystać z pełnego uruchomionego przykładu, zapoznaj się z poniższym przykładem języka C#.

W przeciwnym razie postępuj zgodnie z poniższym przewodnikiem, aby utworzyć niezawodny czytnik wykazu.

Inicjowanie kursora

Pierwszym krokiem tworzenia niezawodnego czytnika wykazu jest zaimplementowanie kursora. Aby uzyskać szczegółowe informacje na temat projektowania kursora wykazu, zobacz dokument referencyjny wykazu. Krótko mówiąc, kursor jest punktem w czasie, do którego przetworzyliśmy zdarzenia w wykazie. Zdarzenia w wykazie reprezentują publikowane pakiety i inne zmiany w pakiecie. Jeśli dbasz o wszystkie pakiety, które kiedykolwiek zostały opublikowane w programie NuGet (od początku czasu), zainicjuj kursor na znacznik czasu "minimalnej wartości" (np. DateTime.MinValue na platformie .NET). Jeśli zależy Ci tylko na pakietach opublikowanych od teraz, użyj bieżącego znacznika czasu jako początkowej wartości kursora.

W tym przewodniku zainicjujemy kursor na sygnaturę czasową godzinę temu. Na razie wystarczy zapisać ten znacznik czasu w pamięci.

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

Określanie adresu URL indeksu wykazu

Lokalizacja każdego zasobu (punktu końcowego) w interfejsie API NuGet powinna zostać odnaleziona przy użyciu indeksu usługi. Ponieważ ten przewodnik koncentruje się na nuget.org, będziemy używać indeksu usługi nuget.org.

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

Dokument usługi to dokument JSON zawierający wszystkie zasoby w nuget.org. Wyszukaj zasób o @type wartości Catalog/3.0.0właściwości . Skojarzona @id wartość właściwości to adres URL samego indeksu wykazu.

Znajdowanie nowych listów wykazu

Korzystając z @id wartości właściwości znalezionej w poprzednim kroku, pobierz indeks katalogu:

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

Deserializowanie indeksu wykazu. Odfiltruj wszystkie obiekty stron wykazu o commitTimeStamp wartości mniejszej lub równej bieżącej wartości kursora.

Dla każdej pozostałej strony wykazu pobierz pełny dokument przy użyciu @id właściwości .

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

Deserializowanie strony wykazu. Odfiltruj wszystkie obiekty liści wykazu o commitTimeStamp wartości mniejszej lub równej bieżącej wartości kursora.

Po pobraniu wszystkich stron wykazu, które nie zostały odfiltrowane, masz zestaw obiektów liści wykazu reprezentujących pakiety, które zostały opublikowane, nie wymienione, wymienione lub usunięte w czasie między znacznikiem czasu kursora a teraz.

Liście wykazu procesów

Na tym etapie możesz wykonać dowolne niestandardowe przetwarzanie w elementach wykazu. Jeśli wszystko, czego potrzebujesz, to identyfikator i wersja pakietu, możesz sprawdzić nuget:id właściwości i nuget:version na obiektach elementów katalogu znalezionych na stronach. Pamiętaj, aby sprawdzić @type właściwość, aby sprawdzić, czy element wykazu dotyczy istniejącego pakietu lub usuniętego pakietu.

Jeśli interesuje Cię metadane dotyczące pakietu (takie jak opis, zależności, rozmiar nupkg itp.), możesz pobrać dokument liścia wykazu przy użyciu @id właściwości .

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

Ten dokument zawiera wszystkie metadane zawarte w zasobie metadanych pakietu i nie tylko!

W tym kroku implementujesz logikę niestandardową. Inne kroki opisane w tym przewodniku są implementowane w prawie taki sam sposób, w jaki nie ma znaczenia, co robisz z listami wykazu.

Pobieranie pliku nupkg

Jeśli chcesz pobrać pliki nupkg dla pakietów znajdujących się w wykazie, możesz użyć zasobu zawartości pakietu. Należy jednak pamiętać, że występuje krótkie opóźnienie między czasem znalezienia pakietu w katalogu a dostępnością w zasobie zawartości pakietu. W związku z tym, jeśli podczas 404 Not Found próby pobrania pliku nupkg dla pakietu znalezionego w wykazie po prostu spróbuj ponownie później. Rozwiązywanie tego opóźnienia jest śledzone przez narzędzie NuGet/NuGetGallery#3455 w witrynie GitHub.

Przenieś kursor do przodu

Po pomyślnym przetworzeniu elementów wykazu należy określić nową wartość kursora do zapisania. W tym celu znajdź maksymalną (najnowszą chronologicznie) commitTimeStamp wszystkie przetworzone elementy wykazu. Jest to nowa wartość kursora. Zapisz go w magazynie trwałym, na przykład w bazie danych, systemie plików lub magazynie obiektów blob. Jeśli chcesz uzyskać więcej elementów wykazu, po prostu zacznij od pierwszego kroku, inicjując wartość kursora z tego magazynu trwałego.

Jeśli aplikacja zgłasza wyjątek lub błędy, nie przesuwaj kursora do przodu. Przesunięcie kursora do przodu ma znaczenie, że nigdy więcej nie trzeba przetwarzać elementów wykazu przed kursorem.

Jeśli z jakiegoś powodu masz usterkę w sposobie przetwarzania liści wykazu, możesz po prostu przesunąć kursor do tyłu w czasie i zezwolić kodowi na ponowne przetwarzanie starych elementów wykazu.

Przykładowy kod w języku C#

Ponieważ wykaz jest zestawem dokumentów JSON dostępnych za pośrednictwem protokołu HTTP, można wchodzić w interakcje z dowolnym językiem programowania, który ma klienta HTTP i deserializatora JSON.

Przykłady języka C# są dostępne w repozytorium NuGet/Samples.

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

Zestaw SDK wykazu

Najprostszym sposobem korzystania z wykazu jest użycie wstępnie wydanego pakietu NuGet.Protocol.Catalog.NET catalog SDK , który jest dostępny w usłudze Azure Artifacts przy użyciu następującego adresu URL źródła pakietu NuGet: https://pkgs.dev.azure.com/dnceng/public/_packaging/nuget-build/nuget/v3/index.json.

Ten pakiet można zainstalować w projekcie zgodnym z programem lub nowszym netstandard1.3 (np. .NET Framework 4.6).

Przykład użycia tego pakietu jest dostępny w witrynie GitHub w projekcie NuGet.Protocol.Catalog.Sample.

Przykładowe dane wyjściowe

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.

Minimalna próbka

Aby uzyskać przykład z mniejszą liczbą zależności ilustrujących interakcję z wykazem bardziej szczegółowo, zobacz przykładowy projekt CatalogReaderExample. Projekt jest przeznaczony dla celów netcoreapp2.0 i zależy od nuGet.Protocol 4.4.0 (do rozpoznawania indeksu usługi) i Newtonsoft.Json 9.0.1 (w przypadku deserializacji JSON).

Główna logika kodu jest widoczna w pliku Program.cs.

Przykładowe dane wyjściowe

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.