Nuget - metadata service endpoints
What does this MR do?
This MR adds the metadata service endpoints for the NuGet API. See https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource.
This service is used by the nuget
CLI command to get the available version of a given package.
Related issue #36504 (closed) and #20050 (closed)
This MR doesn't need documentation or a change log entry.
This MR is gated behind this feature flag (scoped by project): nuget_package_registry
as this MR is part of the nuget MVC (See the epic: &2271 (closed)).
This MR adds the following:
- The endpoints has two urls: one for the "package name" level (
/api/v4/projects/:id/packages/nuget/metadata/*package_name/index
) and one for "package name + package version" level (/api/v4/projects/:id/packages/nuget/metadata/*package_name/:package_version
). - Both urls must reply a proper JSON structure (see below). The "package name" level response describes all available version for the given package. The "package name + version" level response obviously describes a single package+version.
- The structure for the "package name+version" level is reused at the "package name" level.
- Two presenters have been added for each level:
Packages::Nuget::PackagesMetadataPresenter
(presentn
packages) andPackages::Nuget::PackageMetadataPresenter
(present a single package) - Since we can't use a presenter in an other one, common functions have been centralized in a helper:
API::Helpers::Packages::Nuget::MetadataPresenterHelpers
. - The endpoints will use a common finder:
Packages::Nuget::PackagesFinder
that can searchnuget
packages byname
orname
+version
. - For this first implementation, the finder will limit the number of returned packages to 50, with a new scope added to
Packages::Package
- The endpoint for the download service has been added so that the metadata endpoints can reference it through a grape path helper. It's empty for now. It will properly implemented in a future MR.
Screenshots
Here is the json response for the "package name" level:
GET https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/index.json
{
"count": 1,
"items": [
{
"@id": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.2.json",
"lower": "1.0.0",
"upper": "1.0.2",
"count": 3,
"items": [
{
"@id": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.2.json",
"packageContent": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/download/DummyProject.DummyPackage/1.0.2/dummyproject.dummypackage.1.0.2.nupkg",
"catalogEntry": {
"@id": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.2.json",
"authors": "",
"dependencyGroups": [],
"id": "DummyProject.DummyPackage",
"version": "1.0.2",
"packageContent": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/download/DummyProject.DummyPackage/1.0.2/dummyproject.dummypackage.1.0.2.nupkg",
"summary": ""
}
},
{
"@id": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.1.json",
"packageContent": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/download/DummyProject.DummyPackage/1.0.1/dummyproject.dummypackage.1.0.1.nupkg",
"catalogEntry": {
"@id": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.1.json",
"authors": "",
"dependencyGroups": [],
"id": "DummyProject.DummyPackage",
"version": "1.0.1",
"packageContent": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/download/DummyProject.DummyPackage/1.0.1/dummyproject.dummypackage.1.0.1.nupkg",
"summary": ""
}
},
{
"@id": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.0.json",
"packageContent": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/download/DummyProject.DummyPackage/1.0.0/dummyproject.dummypackage.1.0.0.nupkg",
"catalogEntry": {
"@id": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.0.json",
"authors": "",
"dependencyGroups": [],
"id": "DummyProject.DummyPackage",
"version": "1.0.0",
"packageContent": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/download/DummyProject.DummyPackage/1.0.0/dummyproject.dummypackage.1.0.0.nupkg",
"summary": ""
}
}
]
}
]
}
Here is the json response for the "package name+version" level:
GET https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.1.json
{
"@id": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.1.json",
"packageContent": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/download/DummyProject.DummyPackage/1.0.1/dummyproject.dummypackage.1.0.1.nupkg",
"catalogEntry": {
"@id": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/metadata/DummyProject.DummyPackage/1.0.1.json",
"authors": "",
"dependencyGroups": [],
"id": "DummyProject.DummyPackage",
"version": "1.0.1",
"packageContent": "https://gitlab.local:3443/api/v4/projects/1/packages/nuget/download/DummyProject.DummyPackage/1.0.1/dummyproject.dummypackage.1.0.1.nupkg",
"summary": ""
}
}
Does this MR meet the acceptance criteria?
Conformity
-
Changelog entry -
Documentation (if required) -
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides -
Separation of EE specific content
Availability and Testing
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. -
Tested in all supported browsers
Security
If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:
-
Label as security and @ mention @gitlab-com/gl-security/appsec
-
The MR includes necessary changes to maintain consistency between UI, API, email, or other methods -
Security reports checked/validated by a reviewer from the AppSec team