Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Services API

Services represent backend connections (databases, caches, storage) that handlers can use.

List Services

GET /api/services

Response:

{
  "ok": true,
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Main Database",
      "service_type": "postgres",
      "config": {
        "host": "db.example.com",
        "port": 5432,
        "database": "myapp"
      },
      "enabled": true,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  ]
}

Create Service

POST /api/services
Content-Type: application/json

{
  "name": "Main Database",
  "service_type": "postgres",
  "config": {
    "host": "db.example.com",
    "port": 5432,
    "database": "myapp",
    "username": "app_user",
    "password": "secret"
  },
  "enabled": true
}

Request Body:

FieldTypeRequiredDescription
namestringYesDisplay name
service_typestringYesType of service (see below)
configobjectYesService-specific configuration
enabledboolNoWhether service is active (default: true)

Service Types:

TypeDescription
sqliteSQLite embedded database
postgresPostgreSQL database
mysqlMySQL database
redisRedis cache/store
mongodbMongoDB document database
minioMinIO/S3 object storage
memcachedMemcached cache
ftpFTP/FTPS/SFTP file transfer
emailSMTP email sending

Response:

{
  "ok": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Main Database",
    "service_type": "postgres",
    "config": { ... },
    "enabled": true,
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z"
  }
}

Get Service

GET /api/services/{id}

Update Service

PUT /api/services/{id}
Content-Type: application/json

{
  "name": "Updated Name",
  "config": {
    "host": "new-db.example.com"
  },
  "enabled": false
}

Delete Service

DELETE /api/services/{id}

Activate Service

Start the service actor. This spawns an async task that manages connections to the backend service.

POST /api/services/{id}/activate

Response:

{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "my-storage",
    "service_type": "minio",
    "active": true,
    "message": "MinIO service actor started successfully"
  }
}

Deactivate Service

Stop the service actor. In-flight operations complete before shutdown.

POST /api/services/{id}/deactivate

Response:

{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "my-storage",
    "service_type": "minio",
    "active": false,
    "message": "Service deactivated"
  }
}

Test Service Connection

Test if the service is reachable and properly configured.

POST /api/services/{id}/test

Response (Success):

{
  "ok": true,
  "data": {
    "connected": true,
    "latency_ms": 5,
    "message": "Connection successful"
  }
}

Response (Failure):

{
  "ok": true,
  "data": {
    "connected": false,
    "error": "Connection refused"
  }
}

MinIO File Operations

When a MinIO service is activated, the following endpoints become available for file operations:

List Objects

GET /api/minio/objects
GET /api/minio/objects?prefix=uploads/

Response:

{
  "bucket": "my-bucket",
  "prefix": "",
  "objects": [
    {
      "key": "uploads/file.txt",
      "size": 1234,
      "last_modified": "2025-12-17T00:29:55.205Z"
    }
  ]
}

Upload Object

Upload a file using multipart form data.

POST /api/minio/objects
Content-Type: multipart/form-data

file: (binary data)
key: uploads/myfile.txt

Response:

{
  "key": "uploads/myfile.txt",
  "bucket": "my-bucket",
  "size": 1234,
  "message": "Upload successful"
}

Download Object

GET /api/minio/objects/{key}
GET /api/minio/objects/uploads/myfile.txt

Returns the file content with appropriate Content-Type header based on file extension.

Delete Object

DELETE /api/minio/objects/{key}
DELETE /api/minio/objects/uploads/myfile.txt

Response:

{
  "key": "uploads/myfile.txt",
  "bucket": "my-bucket",
  "deleted": true
}

Service Configuration Examples

PostgreSQL

{
  "service_type": "postgres",
  "config": {
    "host": "localhost",
    "port": 5432,
    "database": "myapp",
    "username": "app_user",
    "password": "secret",
    "ssl_mode": "prefer",
    "pool_size": 10
  }
}

MySQL

{
  "service_type": "mysql",
  "config": {
    "host": "localhost",
    "port": 3306,
    "database": "myapp",
    "username": "app_user",
    "password": "secret",
    "use_ssl": false,
    "pool_size": 10
  }
}

Redis

{
  "service_type": "redis",
  "config": {
    "host": "localhost",
    "port": 6379,
    "password": null,
    "database": 0,
    "use_tls": false,
    "pool_size": 10
  }
}

SQLite

{
  "service_type": "sqlite",
  "config": {
    "path": "/data/app.db",
    "create_if_missing": true
  }
}

MinIO

{
  "service_type": "minio",
  "config": {
    "endpoint": "minio.example.com:9000",
    "access_key": "minioadmin",
    "secret_key": "minioadmin",
    "use_ssl": true,
    "bucket": "uploads"
  }
}

FTP/SFTP

{
  "service_type": "ftp",
  "config": {
    "host": "sftp.example.com",
    "port": 22,
    "username": "user",
    "password": "secret",
    "protocol": "sftp",
    "base_path": "/uploads",
    "timeout_seconds": 30
  }
}

Email (SMTP)

{
  "service_type": "email",
  "config": {
    "host": "smtp.example.com",
    "port": 587,
    "username": "sender@example.com",
    "password": "app-password",
    "encryption": "starttls",
    "from_address": "noreply@example.com",
    "from_name": "My App"
  }
}