Configuration Management
Configuration management is the core capability of the Config Service. The ConfigController at /api/v1/configs provides full CRUD operations for configuration entries with automatic versioning, hierarchical resolution, rollback to any previous version, and category-based organization.
ConfigController Overview
The controller is implemented in ConfigController.java and uses ConfigService and ConfigVersionService for business logic:
@RestController
@RequestMapping("/api/v1/configs")
@Tag(name = "Configuration", description = "Configuration management endpoints")
public class ConfigController {
private final ConfigService configService;
private final ConfigVersionService versionService;
private final ConfigMapper configMapper;
}Create a Configuration Entry
Create a new configuration entry with tenant scoping, category, and value type.
Endpoint: POST /api/v1/configs
Request:
curl -X POST http://localhost:8888/api/v1/configs \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001" \
-d '{
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"configKey": "query.timeout",
"configValue": "60s",
"category": "query-engine",
"description": "Maximum query execution timeout",
"environment": "production",
"valueType": "STRING",
"encrypted": false
}'Response (201 Created):
{
"id": "770e8400-e29b-41d4-a716-446655440000",
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"configKey": "query.timeout",
"configValue": "60s",
"category": "query-engine",
"description": "Maximum query execution timeout",
"environment": "production",
"valueType": "STRING",
"encrypted": false,
"version": 1,
"createdAt": "2026-02-12T10:00:00Z",
"updatedAt": "2026-02-12T10:00:00Z"
}Get Configuration by ID
Retrieve a specific configuration entry by its UUID.
Endpoint: GET /api/v1/configs/{id}
curl http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer ${TOKEN}"Get Configuration by Tenant and Key
Look up a configuration by the combination of tenant ID and configuration key.
Endpoint: GET /api/v1/configs/tenant/{tenantId}/key/{configKey}
curl http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/key/query.timeout \
-H "Authorization: Bearer ${TOKEN}"Hierarchical Resolution
Resolve a configuration key using the four-level hierarchy (global, environment, tenant, tenant+environment). This is the recommended endpoint for services that need the effective configuration value.
Endpoint: GET /api/v1/configs/tenant/{tenantId}/key/{configKey}/resolve
curl "http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/key/query.timeout/resolve?environment=production" \
-H "Authorization: Bearer ${TOKEN}"The resolution order:
- Tenant + environment specific entry
- Tenant-level entry (any environment)
- Global entry (null tenantId)
Get Configuration Value Only
Returns just the value string, useful for lightweight lookups where the full metadata is not needed.
Endpoint: GET /api/v1/configs/tenant/{tenantId}/value/{configKey}
curl "http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/value/query.timeout?environment=production" \
-H "Authorization: Bearer ${TOKEN}"Response:
{
"value": "120s"
}List Tenant Configurations
Retrieve all configurations for a tenant with pagination.
Endpoint: GET /api/v1/configs/tenant/{tenantId}
curl "http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000?page=0&size=20&sort=configKey,asc" \
-H "Authorization: Bearer ${TOKEN}"Response:
{
"content": [
{
"id": "770e8400-...",
"configKey": "ai.model",
"configValue": "gpt-4",
"category": "ai-service",
"version": 3
},
{
"id": "880e8400-...",
"configKey": "query.max-rows",
"configValue": "10000",
"category": "query-engine",
"version": 1
}
],
"totalElements": 42,
"totalPages": 3,
"size": 20,
"number": 0
}Get Configurations by Category
Group configurations by their category (e.g., query-engine, ai-service, bi-service).
Endpoint: GET /api/v1/configs/tenant/{tenantId}/category/{category}
curl http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/category/query-engine \
-H "Authorization: Bearer ${TOKEN}"Search Configurations
Search configurations by key pattern using SQL LIKE matching.
Endpoint: GET /api/v1/configs/tenant/{tenantId}/search
curl "http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/search?pattern=query.%" \
-H "Authorization: Bearer ${TOKEN}"Global Configurations
Retrieve platform-wide default configurations (entries where tenantId is null).
Endpoint: GET /api/v1/configs/global
curl http://localhost:8888/api/v1/configs/global \
-H "Authorization: Bearer ${TOKEN}"Update a Configuration Entry
Update an existing configuration. This automatically creates a new version in the version history.
Endpoint: PUT /api/v1/configs/{id}
curl -X PUT http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001" \
-d '{
"configValue": "120s",
"description": "Increased timeout for enterprise workloads"
}'Every update creates a new version entry in the config_versions table, preserving the complete change history.
Delete a Configuration Entry
Soft-delete a configuration entry with an optional reason for the audit trail.
Endpoint: DELETE /api/v1/configs/{id}
curl -X DELETE "http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000?reason=Deprecated%20setting" \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001"Response: 204 No Content
Version History
Every configuration entry maintains a full version history. Each update increments the version number and stores the previous value.
Get Version History
Endpoint: GET /api/v1/configs/{id}/versions
curl "http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000/versions?page=0&size=20" \
-H "Authorization: Bearer ${TOKEN}"Response:
{
"content": [
{
"id": "ver-003",
"configEntryId": "770e8400-...",
"versionNumber": 3,
"configValue": "120s",
"changedBy": "550e8400-...001",
"changeReason": "Increased for enterprise workloads",
"createdAt": "2026-02-12T14:00:00Z"
},
{
"id": "ver-002",
"configEntryId": "770e8400-...",
"versionNumber": 2,
"configValue": "90s",
"changedBy": "550e8400-...001",
"changeReason": "Performance tuning",
"createdAt": "2026-02-10T09:00:00Z"
},
{
"id": "ver-001",
"configEntryId": "770e8400-...",
"versionNumber": 1,
"configValue": "60s",
"changedBy": "system",
"changeReason": "Initial creation",
"createdAt": "2026-01-15T08:00:00Z"
}
],
"totalElements": 3,
"totalPages": 1
}Get Specific Version
Endpoint: GET /api/v1/configs/{id}/versions/{versionNumber}
curl http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000/versions/1 \
-H "Authorization: Bearer ${TOKEN}"Rollback to Previous Version
Rollback a configuration entry to any previous version. The rollback itself creates a new version entry.
Endpoint: POST /api/v1/configs/{id}/rollback
curl -X POST http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000/rollback \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001" \
-d '{
"versionNumber": 1,
"reason": "Reverting to original timeout due to downstream issues"
}'Response (200 OK):
{
"id": "770e8400-...",
"configKey": "query.timeout",
"configValue": "60s",
"version": 4,
"updatedAt": "2026-02-12T16:00:00Z"
}The rollback creates version 4 with the value from version 1. The version history is never rewritten -- it always moves forward.
Bulk Import
Import multiple configuration entries for a tenant in a single request.
Endpoint: POST /api/v1/configs/tenant/{tenantId}/import
curl -X POST http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/import \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001" \
-d '[
{
"configKey": "query.timeout",
"configValue": "60s",
"category": "query-engine"
},
{
"configKey": "query.max-rows",
"configValue": "10000",
"category": "query-engine"
},
{
"configKey": "ai.model",
"configValue": "gpt-4",
"category": "ai-service"
}
]'Export Configurations
Export all configurations for a tenant as a key-value map.
Endpoint: GET /api/v1/configs/tenant/{tenantId}/export
curl http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/export \
-H "Authorization: Bearer ${TOKEN}"Response:
{
"query.timeout": "60s",
"query.max-rows": "10000",
"ai.model": "gpt-4",
"bi.default-chart-type": "bar"
}Error Codes
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid request body or parameters |
| 404 | CONFIG_NOT_FOUND | Configuration entry does not exist |
| 409 | CONFIG_KEY_EXISTS | Duplicate key for the same tenant |
| 422 | INVALID_VALUE_TYPE | Value does not match declared type |
| 500 | INTERNAL_ERROR | Unexpected server error |