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.0
wł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.