The API Service is the primary entry point for managing configurations. It exposes a gRPC API for uploading, retrieving, listing, and deleting configs, as well as managing rollouts and rollbacks.
The API Service handles all configuration lifecycle operations. When a config is uploaded, it is validated (via the Validation Service), stored in PostgreSQL, and events are published to Kafka for downstream consumers.
- Config upload with format detection (JSON/YAML)
- Inline syntax validation + remote validation via Validation Service
- Versioned config storage (metadata + content split across tables)
- Gradual rollout management with percentage-based deployment
- Rollback to any previous version
- Kafka event publishing for config changes
- StatsD metrics for all operations
- Audit logging for every action
Defined in proto/api.proto as ConfigAPIService:
| RPC | Description |
|---|---|
UploadConfig |
Upload a new config version for a service |
GetConfig |
Retrieve a config by ID |
ListConfigs |
List all config versions for a service |
DeleteConfig |
Delete a config by ID |
StartRollout |
Begin gradual rollout of a config |
GetRolloutStatus |
Check rollout progress |
Rollback |
Revert to a previous config version |
┌─────────────────────────────────────────────────────┐
│ API Service │
│ │
│ ┌───────────┐ ┌────────────┐ ┌───────────────┐ │
│ │ gRPC │ │ Validation │ │ Database │ │
│ │ Server │──│ Client │──│ Manager │ │
│ │ (:8081) │ │ (→ :8083) │ │ (PostgreSQL) │ │
│ └───────────┘ └────────────┘ └───────────────┘ │
│ │ │ │
│ ┌────▼──────┐ ┌─────────▼──────┐ │
│ │ Kafka │ │ StatsD Client │ │
│ │ Producer │ │ (Metrics) │ │
│ └───────────┘ └────────────────┘ │
└─────────────────────────────────────────────────────┘
- Client sends
UploadConfigRequestwith service name, content, and format - API Service runs inline syntax validation (bracket matching, trailing comma detection)
- If Validation Service is available, sends content for full validation (schema, rules, ranges)
- On success: stores metadata in
config_metadata, content inconfig_data - Publishes
config_uploadedevent to Kafka - Records audit log entry
- Returns config ID and version to client
Core gRPC service implementation:
UploadConfig()- Validates and stores new configsGetConfig()- Retrieves config by ID (joins metadata + data)ListConfigs()- Lists versions for a serviceDeleteConfig()- Removes config from both tablesStartRollout()- Creates rollout entry inrollout_stateGetRolloutStatus()- Queries rollout progressRollback()- Copies previous version as new latest
Helper methods:
ValidateContent()- Inline JSON syntax validation (brackets, trailing commas)PublishEvent()- Kafka event publishingComputeHash()- SHA-256 content hashingGenerateConfigId()- Generates{service}-v{version}IDs
gRPC client for the Validation Service:
- Connects to address from config (
validation_service.address) - Sends config content for full validation (syntax, schema, rules, ranges)
- Returns validation errors and warnings
- Gracefully degrades if validation service is unavailable
PostgreSQL operations:
StoreConfig()- Inserts intoconfig_metadata+config_dataGetConfig()- Joins metadata and data by config_idListConfigs()- Queries by service nameDeleteConfig()- Removes from both tablesCreateRollout()- Inserts intorollout_stateGetRolloutState()- Queries rollout progressRecordAuditEvent()- Writes toaudit_logwith JSONB details
YAML configuration loading with these sections:
server- Port, max connectionspostgres- Host, port, database, credentialskafka- Broker address, topicredis- Host, port, cache TTLstatsd- Host, port, prefixvalidation_service- Validation service address
Docker (config/api-service.yml):
server:
port: 8081
postgres:
host: postgres
port: 5432
kafka:
brokers: kafka:9092
validation_service:
address: validation-service:8083Local (config/api-service-local.yml):
postgres:
host: localhost
kafka:
brokers: localhost:9092
validation_service:
address: localhost:8083# Build locally
make api-service
# Run locally
./bin/api-service config/api-service-local.yml
# Build and run in Docker
make services
docker compose logs -f api-serviceapi.upload.count- Upload requestsapi.get.count- Get requestsapi.list.count- List requestsapi.delete.count- Delete requestsapi.validation.pass/api.validation.fail- Validation results
src/api-service/
├── main.cpp # Entry point, gRPC server setup
├── api_service.cpp # gRPC method implementations
├── validation_client.cpp # Validation Service gRPC client
├── database_manager.cpp # PostgreSQL operations
└── config.cpp # YAML config loading
include/api_service/
├── api_service.h
├── validation_client.h
├── database_manager.h
└── config.h