Skip to content

[ENHANCEMENT] Migrate NuGet V2 APIs to V3 APIs #5331

Description

Please confirm these before moving forward.

  • I have searched for my feature proposal and have not found a work-in-progress/duplicate/resolved/discarded issue.
  • This improvement refers to an existing feature. If you want to suggest a new feature, please use this template.
  • This improvement is not a bug. If you want to report a bug, please use this template.

Describe the improvement

Hi there I'm Charles Bissonnette, the Engineering Manager for http://NuGet.Org and I would like to bring this issue to the team. UniGetUI is still relying on V2 NuGet API and our telemetry shows that UniGetUI ends up consuming a huge portion of DataBase's DTU. It is important that you migrate UniGetUI's direct NuGet V2/OData integration to NuGet V3 for the generic NuGet-backed managers (.NET Tool, Windows PowerShell, and PowerShell 7), while preserving compatibility for feeds that cannot provide V3 resources.

Current implementation

The shared implementation is primarily in:

  • src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs
  • src/UniGetUI.PackageEngine.Managers.Generic.NuGet/Internal/NuGetManifestLoader.cs
  • src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGetDetailsHelper.cs

It currently uses V2/OData endpoints such as Search(), Packages(), FindPackagesById(), Packages(Id=...,Version=...), and GetUpdates(), and parses Atom/OData XML responses.

Proposed implementation steps

  1. Inventory and define compatibility boundaries

    • Enumerate every direct V2 URL, OData query, XML response parser, and test fixture in the generic NuGet implementation.
    • Keep Chocolatey's choco CLI integration separate; do not convert it solely because Chocolatey sources use /api/v2/.
    • Identify which configured sources support a NuGet V3 service index and define the fallback behavior for sources that do not.
  2. Introduce a NuGet V3 resource-index client

    • Add a focused internal client/abstraction that loads {source}/index.json.
    • Parse the service index and select resources by advertised @type, including SearchQueryService, RegistrationsBaseUrl, and PackageBaseAddress/3.0.0 (or compatible versions).
    • Normalize source URLs and cache the resolved resource index per source for the lifetime of the relevant operation/session.
    • Handle unavailable or malformed indexes with useful logging and a controlled V2 fallback where supported.
  3. Migrate package search

    • Replace V2 Search() and Packages() URL construction in BaseNuGet.FindPackages_UnSafe() with the V3 SearchQueryService.
    • Send the query using V3 parameters (q, skip, take, prerelease, and semVerLevel where supported).
    • Deserialize V3 JSON instead of extracting <entry> elements with regular expressions.
    • Preserve the existing result limit, pagination, prerelease behavior, source association, duplicate handling, and highest-version selection.
    • Preserve the intent of UseSubstringSearch; use exact package-ID/version resources where a search endpoint cannot provide equivalent behavior.
  4. Replace batch update lookup

    • Remove the dependency on V2 GetUpdates(), which has no direct V3 equivalent.
    • For each installed package/source group, obtain available versions and relevant registration metadata using V3 PackageBaseAddress and/or RegistrationsBaseUrl resources.
    • Compare versions locally using the existing version semantics, including prerelease filtering and ignoring versions that are not newer.
    • Preserve package scope, source identity, update dates, logging, and failure reporting.
    • Add bounded concurrency and caching so update checks do not create unbounded request fan-out.
  5. Migrate package versions and package content URLs

    • Replace FindPackagesById() in BaseNuGetDetailsHelper with the V3 flat-container version index:
      {packageBaseAddress}/{lowercase-id}/index.json.
    • Update NuGetManifestLoader.GetNuPkgUrl() to use the V3 flat-container package path:
      {packageBaseAddress}/{lowercase-id}/{lowercase-version}/{lowercase-id}.{lowercase-version}.nupkg.
    • Account for normalized lowercase IDs and versions, URL escaping, and feeds with nonstandard resource URL layouts.
    • Add tests for IDs and versions containing characters that require normalization or escaping.
  6. Migrate package metadata and details

    • Replace the V2 Packages(Id='...',Version='...') manifest URL in NuGetManifestLoader with V3 registration metadata and/or the package .nuspec URL.
    • Adapt BaseNuGetDetailsHelper to consume V3 JSON metadata and package .nuspec content rather than depending on V2 Atom fields such as <d:Description>, <d:Dependencies>, and <d:IconUrl>.
    • Preserve descriptions, authors/publishers, licenses, release notes, update dates, dependencies, icon URLs, installer URLs, installer sizes, and cached manifest behavior.
    • Prefer structured parsing over regular-expression parsing where practical, while retaining robust handling for incomplete package metadata.
  7. Update manager source definitions

    • Change the .NET Tool default and known source to https://api.nuget.org/v3/index.json.
    • Change the PowerShell Gallery sources to their supported V3 service-index endpoint, confirming the endpoint and behavior for both Windows PowerShell and PowerShell 7.
    • Preserve custom-source support and V2 fallback for feeds that do not expose the required V3 resources.
    • Do not change Chocolatey's source behavior unless a compatible V3 migration is explicitly validated.
  8. Add migration and regression tests

    • Add HTTP fixture tests for service-index parsing and resource selection.
    • Add tests for V3 search JSON, pagination, prerelease filtering, duplicate versions, and malformed responses.
    • Add tests for flat-container version enumeration and package URL generation.
    • Add tests for registration metadata and .nuspec parsing, including dependencies, icons, licenses, and missing fields.
    • Add tests for local update comparison and bounded/cached requests.
    • Retain V2 fallback tests for custom feeds where fallback is implemented.
    • Update existing tests that assert V2 URLs, V2 XML, or V2-specific behavior.
  9. Documentation and rollout

    • Update code comments and documentation that describe the integration as V2/OData-specific.
    • Document supported V3 resources and the fallback behavior.
    • Run the relevant test projects, formatting checks, and build checks.
    • Review behavior against nuget.org, PowerShell Gallery, a V2-only custom feed, and a custom V3 feed before removing any fallback code.

Acceptance criteria

  • The .NET Tool, Windows PowerShell, and PowerShell 7 managers use NuGet V3 resources for supported feeds.
  • Search, version listing, package details, package downloads, icons, dependencies, and update detection continue to work.
  • Prerelease filtering, pagination, caching, logging, proxy behavior, and source identity remain functional.
  • V2-only custom sources do not regress when fallback is available; unsupported feeds fail clearly when neither API is usable.
  • Chocolatey's CLI-based behavior remains unchanged.
  • Automated tests cover V3 resource discovery, search, metadata, versions, updates, content URLs, and fallback behavior.

Describe how this improvement could help users

Moving from NuGet V2/OData to V3 would align UniGetUI with the current NuGet server API model, avoid dependence on legacy XML/OData endpoints, improve interoperability with modern NuGet-compatible feeds, and provide a more maintainable foundation for search, metadata, package downloads, and update detection. It should also make feed capabilities explicit through service-index discovery and allow UniGetUI to retain compatibility with older custom repositories where possible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementAn improvement to WingetUI

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions