Запрос всех пакетов, опубликованных на сайте nuget.org
Типичным шаблоном запроса для устаревшего OData V2 API было перечисление всех пакетов, опубликованных на сайте nuget.org, с сортировкой по времени публикации. Подобный запрос к сайту nuget.org может потребоваться в самых разных ситуациях:
- Репликация всего сайта nuget.org
- Проверка на наличие новых версий для пакетов
- Поиск пакетов, зависящих от вашего пакета
Ранее для этого обычно выполнялась сортировка сущности пакета OData по метке времени и просмотр огромного результирующего набора с помощью параметров skip
и top
(размер страницы). К сожалению, у этого способа есть несколько недостатков:
- Возможность отсутствия пакетов, так как запросы выполняются для данных, которые часто меняют порядок.
- Большое время отклика запроса, так как запросы не оптимизируются (лучше всего оптимизированы запросы, поддерживающие основной сценарий для официального клиента NuGet).
- Использование нерекомендуемого и незадокументированного API, из-за чего не гарантируется поддержка этих запросов в будущем.
- Неспособность воспроизвести журнал в том порядке, в котором он формировался.
По этой причине можно воспользоваться приведенным ниже руководством, чтобы обеспечить более надежную и прогнозируемую работу в вышеупомянутых сценариях.
Обзор
Центральной точкой этого руководства является ресурс в API NuGet, называемый каталогом. Каталог — это API только для добавления, который позволяет вызывающей стороне просматривать полный журнал пакетов, добавленных, измененных и удаленных из nuget.org. Если вы заинтересованы во всех или даже подмножествах пакетов, опубликованных в nuget.org, каталог является отличным способом оставаться в актуальном состоянии с набором доступных пакетов в настоящее время.
Это руководство имеет общий характер. Если вы хотите получить более подробные сведения о каталоге, см. соответствующий справочник по API.
Приведенные ниже шаги можно реализовать на любом языке программирования. Если вам нужен полноценный рабочий пример, обратите внимание на указанный ниже пример на C#.
В противном случае выполните приведенные ниже инструкции, чтобы создать надежное средство чтения каталога.
Инициализация курсора
Первым шагом в создании надежного средства чтения каталога является реализация курсора. Полные сведения о проектировании курсора каталога см. в справочном документе по каталогу. Если кратко, курсор является точкой во времени, до которой вы обработали события в каталоге. События в каталоге представляют публикации пакетов и другие их изменения. Если вас интересуют все пакеты, когда-либо опубликованные в NuGet (с самого его появления), нужно инициализировать курсор с минимальной меткой времени (например, DateTime.MinValue
в .NET). Если вам нужны только пакеты, опубликованные с текущего момента, нужно использовать текущую метку времени в качестве начального значения курсора.
В этом руководстве мы инициализируем курсор с меткой времени на час раньше текущего момента. Пока просто сохраните метку времени в памяти.
DateTime cursor = DateTime.UtcNow.AddHours(-1);
Определение URL-адреса индекса каталога
Нужно определить расположение каждого ресурса (конечная точка) в API NuGet с помощью индекса службы. Так как это руководство ориентировано на сайт nuget.org, мы будем использовать индекс службы для nuget.org.
GET https://api.nuget.org/v3/index.json
Документ службы — это документ JSON, содержащий все ресурсы в nuget.org. Найдите ресурс со значением @type
Catalog/3.0.0
свойства . Соответствующее значение свойства @id
является URL-адресом для самого индекса каталога.
Поиск новых конечных объектов каталога
Используя значение свойства @id
, найденное на предыдущем шаге, скачайте индекс каталога:
GET https://api.nuget.org/v3/catalog0/index.json
Десериализуйте индекс каталога. Отфильтруйте все объекты страниц каталога, у которых commitTimeStamp
меньше или равен текущему значению курсора.
Для каждой из оставшихся страниц каталога скачайте полный документ, используя свойство @id
.
GET https://api.nuget.org/v3/catalog0/page2926.json
Десериализуйте страницу каталога. Отфильтруйте все конечные объекты каталога, у которых commitTimeStamp
меньше или равен текущему значению курсора.
Скачав все неотфильтрованные страницы каталога, вы получите набор конечных объектов каталога, представляющих пакеты, которые были опубликованы, исключены из списка, добавлены в список или удалены за период между меткой времени вашего курсора и текущим моментом.
Обработка конечных объектов каталога
На этом этапе вы можете выполнить любую пользовательскую обработку элементов каталога. Если вам нужны только идентификатор и версия пакета, можно просмотреть свойства nuget:id
и nuget:version
для объектов элементов каталога, найденных на этих страницах. Обязательно просмотрите свойство @type
, чтобы узнать, касается ли элемент каталога существующего или удаленного пакета.
Если вам нужны метаданные о пакете (например, описание, зависимости, nupkg size и т. д.), вы можете получить конечный документ каталога с помощью @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#
Так как каталог представляет собой набор документов JSON, доступных по протоколу HTTP, с ним можно взаимодействовать с помощью любого языка программирования, имеющего HTTP-клиент и десериализатор JSON.
Примеры на C# доступны в репозитории NuGet/Samples.
git clone https://github.com/NuGet/Samples.git
Пакет SDK каталога
Самый простой способ работы с каталогом — использовать предварительный выпуск пакета SDK NuGet.Protocol.Catalog
для каталога .NET. Пакет доступен в Azure Artifacts по следующему URL-адресу источника пакетов NuGet: 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.