fix(api): document database and resource list responses in OpenAPI

Add a Database schema and use it for GET /databases and
GET /databases/{uuid}, type the GET /resources items, and stop
requiring both environment_name and environment_uuid on create
endpoints. KeyDB now returns database_type like the other engines.

Closes #10449

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-10-27 14:42:29 +01:00
co-authored by Claude Opus 5.5
parent 5a08c35e7d
commit 80df5431dc
10 changed files with 984 additions and 115 deletions
@@ -381,7 +381,7 @@ class ApplicationsController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'git_repository', 'git_branch', 'build_pack'],
required: ['project_uuid', 'server_uuid', 'git_repository', 'git_branch', 'build_pack'],
properties: [
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
@@ -591,7 +591,7 @@ class ApplicationsController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'github_app_uuid', 'git_repository', 'git_branch', 'build_pack'],
required: ['project_uuid', 'server_uuid', 'github_app_uuid', 'git_repository', 'git_branch', 'build_pack'],
properties: [
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
@@ -801,7 +801,7 @@ class ApplicationsController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'private_key_uuid', 'git_repository', 'git_branch', 'build_pack'],
required: ['project_uuid', 'server_uuid', 'private_key_uuid', 'git_repository', 'git_branch', 'build_pack'],
properties: [
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
@@ -1011,7 +1011,7 @@ class ApplicationsController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'dockerfile'],
required: ['project_uuid', 'server_uuid', 'dockerfile'],
properties: [
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
@@ -1190,7 +1190,7 @@ class ApplicationsController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'docker_registry_image_name'],
required: ['project_uuid', 'server_uuid', 'docker_registry_image_name'],
properties: [
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
@@ -352,8 +352,8 @@ class DatabasesController extends Controller
response: 200,
description: 'Get all databases',
content: new OA\JsonContent(
type: 'string',
example: 'Content is very complex. Will be implemented later.',
type: 'array',
items: new OA\Items(ref: '#/components/schemas/Database'),
),
),
new OA\Response(
@@ -511,11 +511,8 @@ class DatabasesController extends Controller
responses: [
new OA\Response(
response: 200,
description: 'Get all databases',
content: new OA\JsonContent(
type: 'string',
example: 'Content is very complex. Will be implemented later.',
),
description: 'Get database by UUID',
content: new OA\JsonContent(ref: '#/components/schemas/Database'),
),
new OA\Response(
response: 401,
@@ -1550,7 +1547,7 @@ class DatabasesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
@@ -1623,7 +1620,7 @@ class DatabasesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
@@ -1692,7 +1689,7 @@ class DatabasesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
@@ -1760,7 +1757,7 @@ class DatabasesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
@@ -1829,7 +1826,7 @@ class DatabasesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
@@ -1898,7 +1895,7 @@ class DatabasesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
@@ -1970,7 +1967,7 @@ class DatabasesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
@@ -2042,7 +2039,7 @@ class DatabasesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
@@ -2111,7 +2108,7 @@ class DatabasesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'server_uuid' => ['type' => 'string', 'description' => 'UUID of the server'],
'project_uuid' => ['type' => 'string', 'description' => 'UUID of the project'],
+97
View File
@@ -35,6 +35,103 @@ use OpenApi\Attributes as OA;
new OA\Property(property: 'finished_at', type: 'string', format: 'date-time', nullable: true),
],
),
new OA\Schema(
schema: 'Database',
description: 'Standalone database. The fields that start with an engine name (for example postgres_ or redis_) are only returned for that engine. Passwords, connection URLs and init_scripts are only returned for tokens with the read:sensitive or root ability.',
type: 'object',
properties: [
new OA\Property(property: 'uuid', type: 'string'),
new OA\Property(property: 'name', type: 'string'),
new OA\Property(property: 'description', type: 'string', nullable: true),
new OA\Property(property: 'database_type', type: 'string', enum: ['standalone-postgresql', 'standalone-redis', 'standalone-mongodb', 'standalone-mysql', 'standalone-mariadb', 'standalone-keydb', 'standalone-dragonfly', 'standalone-clickhouse', 'standalone-sqlite']),
new OA\Property(property: 'image', type: 'string'),
new OA\Property(property: 'status', type: 'string', description: 'Container status and health, for example running:healthy or exited:unhealthy.'),
new OA\Property(property: 'server_status', type: 'boolean', description: 'True when the server of the database is reachable and usable.'),
new OA\Property(property: 'environment_id', type: 'integer'),
new OA\Property(property: 'environment', ref: '#/components/schemas/Environment', description: 'Only returned by GET /databases/{uuid}. Includes the project.'),
new OA\Property(property: 'destination_id', type: 'integer'),
new OA\Property(property: 'destination_type', type: 'string'),
new OA\Property(
property: 'destination',
description: 'Docker network destination of the database, with its server.',
type: 'object',
properties: [
new OA\Property(property: 'uuid', type: 'string'),
new OA\Property(property: 'name', type: 'string'),
new OA\Property(property: 'network', type: 'string'),
new OA\Property(property: 'server_id', type: 'integer'),
new OA\Property(property: 'server', ref: '#/components/schemas/Server'),
new OA\Property(property: 'created_at', type: 'string', format: 'date-time'),
new OA\Property(property: 'updated_at', type: 'string', format: 'date-time'),
],
),
new OA\Property(property: 'is_public', type: 'boolean', description: 'Not returned for SQLite.'),
new OA\Property(property: 'public_port', type: 'integer', nullable: true, description: 'Not returned for SQLite.'),
new OA\Property(property: 'public_port_timeout', type: 'integer', nullable: true, description: 'Proxy timeout of the public port in seconds. Not returned for SQLite.'),
new OA\Property(property: 'ports_mappings', type: 'string', nullable: true, description: 'Comma-separated host:container port mappings. Not returned for SQLite.'),
new OA\Property(property: 'enable_ssl', type: 'boolean', description: 'Not returned for ClickHouse and SQLite.'),
new OA\Property(property: 'ssl_mode', type: 'string', nullable: true, description: 'PostgreSQL, MongoDB and MySQL only.'),
new OA\Property(property: 'internal_db_url', type: 'string', nullable: true, description: 'Connection URL inside the Docker network. Contains the password. Not returned for SQLite.'),
new OA\Property(property: 'external_db_url', type: 'string', nullable: true, description: 'Public connection URL, when the database is public. Contains the password. Not returned for SQLite.'),
new OA\Property(property: 'init_scripts', type: 'array', nullable: true, items: new OA\Items(type: 'object', properties: [new OA\Property(property: 'index', type: 'integer'), new OA\Property(property: 'filename', type: 'string'), new OA\Property(property: 'content', type: 'string')]), description: 'PostgreSQL only.'),
new OA\Property(property: 'custom_docker_run_options', type: 'string', nullable: true),
new OA\Property(property: 'is_log_drain_enabled', type: 'boolean'),
new OA\Property(property: 'is_include_timestamps', type: 'boolean', description: 'Not returned for MariaDB.'),
new OA\Property(property: 'include_coolify_default_variables', type: 'boolean'),
new OA\Property(property: 'redact_all_env_values_in_logs', type: 'boolean'),
new OA\Property(property: 'health_check_enabled', type: 'boolean'),
new OA\Property(property: 'health_check_interval', type: 'integer'),
new OA\Property(property: 'health_check_timeout', type: 'integer'),
new OA\Property(property: 'health_check_retries', type: 'integer'),
new OA\Property(property: 'health_check_start_period', type: 'integer'),
new OA\Property(property: 'limits_memory', type: 'string'),
new OA\Property(property: 'limits_memory_swap', type: 'string'),
new OA\Property(property: 'limits_memory_swappiness', type: 'integer'),
new OA\Property(property: 'limits_memory_reservation', type: 'string'),
new OA\Property(property: 'limits_cpus', type: 'string'),
new OA\Property(property: 'limits_cpuset', type: 'string', nullable: true),
new OA\Property(property: 'limits_cpu_shares', type: 'integer'),
new OA\Property(property: 'config_hash', type: 'string', nullable: true, description: 'Internal hash that Coolify uses to find configuration changes that need a restart. It changes only when the database starts, so do not use it to compare configurations.'),
new OA\Property(property: 'restart_count', type: 'integer'),
new OA\Property(property: 'last_restart_at', type: 'string', format: 'date-time', nullable: true),
new OA\Property(property: 'last_restart_type', type: 'string', nullable: true),
new OA\Property(property: 'last_online_at', type: 'string', nullable: true),
new OA\Property(property: 'started_at', type: 'string', format: 'date-time', nullable: true),
new OA\Property(property: 'backup_configs', type: 'array', items: new OA\Items(type: 'object'), description: 'Only returned by GET /databases. The scheduled backups of the database, as returned by GET /databases/{uuid}/backups.'),
new OA\Property(property: 'postgres_user', type: 'string'),
new OA\Property(property: 'postgres_password', type: 'string', format: 'password'),
new OA\Property(property: 'postgres_db', type: 'string'),
new OA\Property(property: 'postgres_initdb_args', type: 'string', nullable: true),
new OA\Property(property: 'postgres_host_auth_method', type: 'string', nullable: true),
new OA\Property(property: 'postgres_conf', type: 'string', nullable: true),
new OA\Property(property: 'redis_password', type: 'string', format: 'password'),
new OA\Property(property: 'redis_conf', type: 'string', nullable: true),
new OA\Property(property: 'mongo_initdb_root_username', type: 'string'),
new OA\Property(property: 'mongo_initdb_root_password', type: 'string', format: 'password'),
new OA\Property(property: 'mongo_initdb_database', type: 'string'),
new OA\Property(property: 'mongo_conf', type: 'string', nullable: true),
new OA\Property(property: 'mysql_user', type: 'string'),
new OA\Property(property: 'mysql_password', type: 'string', format: 'password'),
new OA\Property(property: 'mysql_root_password', type: 'string', format: 'password'),
new OA\Property(property: 'mysql_database', type: 'string'),
new OA\Property(property: 'mysql_conf', type: 'string', nullable: true),
new OA\Property(property: 'mariadb_user', type: 'string'),
new OA\Property(property: 'mariadb_password', type: 'string', format: 'password'),
new OA\Property(property: 'mariadb_root_password', type: 'string', format: 'password'),
new OA\Property(property: 'mariadb_database', type: 'string'),
new OA\Property(property: 'mariadb_conf', type: 'string', nullable: true),
new OA\Property(property: 'keydb_password', type: 'string', format: 'password'),
new OA\Property(property: 'keydb_conf', type: 'string', nullable: true),
new OA\Property(property: 'dragonfly_password', type: 'string', format: 'password'),
new OA\Property(property: 'clickhouse_admin_user', type: 'string'),
new OA\Property(property: 'clickhouse_admin_password', type: 'string', format: 'password'),
new OA\Property(property: 'clickhouse_db', type: 'string'),
new OA\Property(property: 'sqlite_databases', type: 'string', description: 'Comma-separated SQLite database file names.'),
new OA\Property(property: 'created_at', type: 'string', format: 'date-time'),
new OA\Property(property: 'updated_at', type: 'string', format: 'date-time'),
new OA\Property(property: 'deleted_at', type: 'string', format: 'date-time', nullable: true),
],
),
],
responses: [
new OA\Response(
@@ -21,10 +21,23 @@ class ResourcesController extends Controller
responses: [
new OA\Response(
response: 200,
description: 'Get all resources',
description: 'Get all applications, services and standalone databases. The other fields of each resource are the fields of the Application, Service or Database schema.',
content: new OA\JsonContent(
type: 'string',
example: 'Content is very complex. Will be implemented later.',
type: 'array',
items: new OA\Items(
type: 'object',
properties: [
new OA\Property(property: 'uuid', type: 'string'),
new OA\Property(property: 'name', type: 'string'),
new OA\Property(property: 'description', type: 'string', nullable: true),
new OA\Property(property: 'type', type: 'string', description: 'application, service, or standalone-<engine> for databases (for example standalone-postgresql).'),
new OA\Property(property: 'status', type: 'string', description: 'For example running:healthy or exited:unhealthy.'),
new OA\Property(property: 'environment_id', type: 'integer'),
new OA\Property(property: 'created_at', type: 'string', format: 'date-time'),
new OA\Property(property: 'updated_at', type: 'string', format: 'date-time'),
],
additionalProperties: true,
),
),
),
new OA\Response(
@@ -302,7 +302,7 @@ class ServicesController extends Controller
mediaType: 'application/json',
schema: new OA\Schema(
type: 'object',
required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'],
required: ['server_uuid', 'project_uuid'],
properties: [
'type' => ['description' => 'The one-click service type (e.g. "actualbudget", "calibre-web", "gitea-with-mysql" ...)', 'type' => 'string'],
'name' => ['type' => 'string', 'maxLength' => 255, 'description' => 'Name of the service.'],