# Galaxy API v3 refactor
[API Spec](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/newswangerd/galaxy-api-v4/master/refactored_v3.yaml).
## Summary
### Why are we doing this?
Please check out our [problem statement](https://docs.google.com/document/d/1w4eWxy05Z6X3SYMOafX3TrXMP5GIVvXQnQTS11LrxKc) for more details, but the core problems we are trying to solve with this refactor are:
1. Inconsistency: v3 of the api is inconsistent between pulp_ansible and galaxy_ng. Pulp_ansible carries the galaxy_ng v3 api, but doesn’t support the namespaces/, sync/ or tasks/ endpoints. Pulp ansible also has a collections/all/ endpoint that is not currently available in galaxy_ng.
2. Lack of content discovery: collections can only be looked up in one repository at a time. This leads to a degraded UX experience in the UI (where searches have to be performed for each repository) and the client (where one server has to be configured for each repository).
3. Incompleteness: content types such as execution environments aren’t supported and critical features such as authentication are only provided in the unsupported _ui endpoint.
### Design
The original v3 implementation worked by scoping the entire v3 api to a single pulp repository. For example:
- `/api/galaxy/content/community/v3/` scopes the entire API to collections found in the `community` repository.
- `/api/galaxy/v3/` defaults to the `published` repository.
- `/api/galaxy/content/rh-certified/v3/` scopes the entire api to the `rh-certified` repository.
This lead to problems 2 and 3. Collections can only be looked up in one repository at a time, and the structure of the API didn't make sense for content types such as execution environments (EEs), because the api is scoped to a pulp_ansible repository and not a pulp_container repository.
To fix these problems, we are planning on adding new endpoints to the v3 API to support missing features such as EEs, user and group management. Since galaxy_ng now supports multiple content types that are from different pulp plugins, the API will be reorganized into sub routes based on the plugin type. Ansible content (collections and possible roles) will reside under `/v3/plugins/ansible`. Execution environments will live under `/v3/plugins/execution-environments`.
To provide backwards compatibility with the existing v3 endpoints the following changes will be made:
- `/v3/namespaces` will be deprecated and redirected to `/v3/plugins/ansible/namespaces`
- `/v3/collections` will be deprecated and redirected to `/v3/plugins/ansible/collections/{repository}/index`
- `/v3/artifacts` will be deprecated and redirected to `/v3/plugins/ansible/collections/{repository}/artifacts`
- `/v3/imports` will be deprecated and redirected to `/v3/plugins/ansible/imports`
The old v3 endpoints will maintain their scope when they are prefixed with `/content/{reposotory}`. For example:
- `/api/galaxy/content/community/v3/collections` will redirect to `/api/galaxy/v3/plugins/ansible/collections/community/index`
- `/api/galaxy/v3/collections` will redirrect to `/api/galaxy/v3/plugins/ansible/collections/published/index`.
These redirects will be handled with 300s if the ansible galaxy client supports them or proxies if clients don't support redirects.
The `/v3/plugin` design allows us to solve problem 1. The `/v3/plugin/ansible` portion of the API will be implemented in pulp ansible and imported into galaxy_ng. `/v3/plugin/execution-environments` will be provided in galaxy_ng using pulp_container.
While it may seem like this increases the inconsistency between galaxy_ng and pulp_ansible, EEs are currently disable-able in galaxy_ng, and the new `/v3/configuration` endpoints (described bellow) will be used to inform clients when features (such as EEs) are disabled. So, while pulp_ansible will be missing the EE portion of the API, from a client perspective, it will just appear as though EEs are disabled when running against pulp_ansible.
## Other API Improvements
This refactor will also contain a number of quality of life improvements such as:
- API roots are navigable. Example:
```
GET /api/v3/plugins/
{
"sub_routes": [
{
"url": "/api/v4/plugins/ansible",
"status": "production"
},
{
"url": "/api/v4/plugins/execution-environments",
"status": "tech_preview"
}
]
}
```
- Summaries of related objects can be selected and embedded in api responses via API query parameters. Example:
```
GET /api/v3/plugin/ansible/namespaces/my_namespace/?include_related=my_permissions
{
"name": "my_namespace"
"related_fields": {
"my_permissions": [
"ansible.update_namespace"
]
}
[...]
}
```
- Improved queryability. All fields that are returned by the API should be queryable using django filters such as `__startswith`, `__contains` `__icontains`, `__lte`, and `__gte`
- This will include any fields that can be included in `include_related`, but not related objects ommitted from `include_related`
- Support for OPTIONS requests
## New APIs
### Collection version search
[API Spec](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/newswangerd/galaxy-api-v4/master/openapi%3A%20galaxy_ng_v4.yml#/Pulp%20Ansible/get-plugin-ansible-search-collection-versions)
This API allows searching all collection versions in hub across all repositories. It would replace the current functionality `_ui/v1/repo/{base_path}` and `_ui/v1/collection-versions` endpoints by providing a flag to return all collection versions or just the latest version in each collection.
This endpoint addresses a couple of important problems in galaxy_ng.
- Repository discovery: provides a mechnisim to find what repositories a collection is in
- Content discovery: provides a way to search which collections have a specific piece of content (such as a role or a module)
- UX Issues: right now, all collection views in the UI have to be scoped to a single repository and it's an awful user experience.
The following related fields can be includeded:
- `namespace`: includes summary of the namespace the version is in
- `metadata`: includes the collection version metadata
- `distributions`: includes a list of the distributions that content is in.
By default this endpoint will only search content that are in distributions that are labelled with `content=public`. Other sets of distributions can be queried using `?distribution_labels=<label>` and a specific repository can be selected using `?distribution=<base_path>`.
### Configuration
[API Spec](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/newswangerd/galaxy-api-v4/master/openapi%3A%20galaxy_ng_v4.yml#/App%20Configuration/get-configuration)
Since the API requires a distribution base_path to publish and download content, this provides a way to configure a default upload/download repo that clients can read.
This also allows clients to look up if content type such as execution environments are supported on the service.
### Object Permissions
[Example for collection namespaces](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/newswangerd/galaxy-api-v4/master/openapi%3A%20galaxy_ng_v4.yml#/Pulp%20Ansible/get-plugins-ansible-namespaces-name-users)
Rather than embedd updating permissions for objects into the object itself, like the old v3 and \_ui apis, object level permissions will be set using `<object_url>/groups` and `<object_url>/users.` These two viewsets will accept PUT operations for setting and updating a list of permissions on the given object and a DELETE operation for removing a list of permissions from a given object.
## Changed APIs
### Namespaces
Container and collection namespaces no longer have the `groups` property. Getting and setting group ownership will be done through the object permissions apis.