Skip to content

Commit

Permalink
Plan HLAPI versioning
Browse files Browse the repository at this point in the history
  • Loading branch information
cconard96 committed Aug 22, 2024
1 parent eb703aa commit d75c417
Show file tree
Hide file tree
Showing 27 changed files with 974 additions and 253 deletions.
16 changes: 16 additions & 0 deletions resources/api_doc.MD
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,19 @@ Alternatively, a REST API interface is available for the raw GraphQL type declar
As is standard with GraphQL, you MUST specify each property that you want to be returned.

For more information about GraphQL, see the [GraphQL documentation](https://graphql.org/learn/).


## API Versioning

The API is versioned by the URL path. If no version is specified, the latest version will be used.
If you specify `v1`, your request will be routed to the legacy API while `v2` and later will be routed to the high-level API.
Example: `/api.php/v2/...`

### Version pinning strategy

When you specify a version in the URL, the API will use the following rules when determining which version to use:
- If only a major version is specified, the latest minor version will be used. For example `/api.php/v2/...` may use `v2.1` if it is the latest version.
- If a major and minor version are specified, the latest patch version will be used. For example `/api.php/v2.1/...` may use `v2.1.3` if it is the latest version.
- If a major, minor, and patch version are specified, that exact version will be used. For example `/api.php/v2.1.3/...` will use `v2.1.3`.

In general, specifying only the major version is sufficient and shouldn't break your application when new versions are released as long as there is a supported version available.
37 changes: 33 additions & 4 deletions src/Glpi/Api/HL/Controller/AbstractController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
use Glpi\Api\HL\Router;
use Glpi\Api\HL\RSQLInput;
use Glpi\Http\JSONResponse;
use Glpi\Http\Request;
use Glpi\Http\Response;
use Glpi\DBAL\QueryExpression;
use Glpi\DBAL\QueryUnion;
Expand Down Expand Up @@ -115,6 +116,16 @@ abstract class AbstractController
]
];

/**
* Get the requested API version from the request
* @param Request $request
* @return string
*/
protected function getAPIVersion(Request $request): string
{
return $request->getHeaderLine('GLPI-API-Version') ?: Router::API_VERSION;
}

/**
* @return array<string, Doc\Schema>
*/
Expand All @@ -124,23 +135,41 @@ protected static function getRawKnownSchemas(): array
}

/**
* Get all known schemas for this controller for the requested API version
* @param ?string $api_version The API version or null if all versions should be returned
* @return array
* @phpstan-return array<string, Doc\Schema>
*/
final public static function getKnownSchemas(): array
final public static function getKnownSchemas(?string $api_version): array
{
$schemas = static::getRawKnownSchemas();
// Allow plugins to inject or modify schemas
$schemas = \Plugin::doHookFunction('redefine_api_schemas', [
'controller' => static::class,
'schemas' => $schemas,
])['schemas'];
return $schemas;

if ($api_version !== null) {
foreach ($schemas as $schema_name => &$schema) {
if (str_starts_with($schema_name, '_')) {
continue;
}
$schema = Doc\Schema::filterSchemaByAPIVersion($schema, $api_version);
}
}
// Remove any null schemas
return array_filter($schemas);
}

protected function getKnownSchema(string $name): ?array
/**
* Get a schema by name and API version
* @param string $name The name of the schema
* @param string $api_version The API version
* @return array|null
*/
protected function getKnownSchema(string $name, string $api_version): ?array
{
$schemas = static::getKnownSchemas();
$schemas = static::getKnownSchemas($api_version);
return array_change_key_case($schemas)[strtolower($name)] ?? null;
}

Expand Down
Loading

0 comments on commit d75c417

Please sign in to comment.