mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-12-13 17:10:36 +00:00
Some checks are pending
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Waiting to run
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Waiting to run
Build , Vet Test, and Lint / Lint Code (push) Waiting to run
Build , Vet Test, and Lint / Build (push) Waiting to run
Tests / Unit Tests (push) Waiting to run
Tests / Integration Tests (push) Waiting to run
292 lines
6.3 KiB
Markdown
292 lines
6.3 KiB
Markdown
# ResolveSpec Configuration System
|
|
|
|
A centralized configuration system with support for multiple configuration sources: config files (YAML, TOML, JSON), environment variables, and programmatic configuration.
|
|
|
|
## Features
|
|
|
|
- **Multiple Config Sources**: Config files, environment variables, and code
|
|
- **Priority Order**: Environment variables > Config file > Defaults
|
|
- **Multiple Formats**: YAML, TOML, JSON supported
|
|
- **Type Safety**: Strongly-typed configuration structs
|
|
- **Sensible Defaults**: Works out of the box with reasonable defaults
|
|
|
|
## Quick Start
|
|
|
|
### Basic Usage
|
|
|
|
```go
|
|
import "github.com/heinhel/ResolveSpec/pkg/config"
|
|
|
|
// Create a new config manager
|
|
mgr := config.NewManager()
|
|
|
|
// Load configuration from file and environment
|
|
if err := mgr.Load(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Get the complete configuration
|
|
cfg, err := mgr.GetConfig()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Use the configuration
|
|
fmt.Println("Server address:", cfg.Server.Addr)
|
|
```
|
|
|
|
### Custom Configuration Paths
|
|
|
|
```go
|
|
mgr := config.NewManagerWithOptions(
|
|
config.WithConfigFile("/path/to/config.yaml"),
|
|
config.WithEnvPrefix("MYAPP"),
|
|
)
|
|
```
|
|
|
|
## Configuration Sources
|
|
|
|
### 1. Config Files
|
|
|
|
Place a `config.yaml` file in one of these locations:
|
|
- Current directory (`.`)
|
|
- `./config/`
|
|
- `/etc/resolvespec/`
|
|
- `$HOME/.resolvespec/`
|
|
|
|
Example `config.yaml`:
|
|
|
|
```yaml
|
|
server:
|
|
addr: ":8080"
|
|
shutdown_timeout: 30s
|
|
|
|
tracing:
|
|
enabled: true
|
|
service_name: "my-service"
|
|
|
|
cache:
|
|
provider: "redis"
|
|
redis:
|
|
host: "localhost"
|
|
port: 6379
|
|
```
|
|
|
|
### 2. Environment Variables
|
|
|
|
All configuration can be set via environment variables with the `RESOLVESPEC_` prefix:
|
|
|
|
```bash
|
|
export RESOLVESPEC_SERVER_ADDR=":9090"
|
|
export RESOLVESPEC_TRACING_ENABLED=true
|
|
export RESOLVESPEC_CACHE_PROVIDER=redis
|
|
export RESOLVESPEC_CACHE_REDIS_HOST=localhost
|
|
```
|
|
|
|
Nested configuration uses underscores:
|
|
- `server.addr` → `RESOLVESPEC_SERVER_ADDR`
|
|
- `cache.redis.host` → `RESOLVESPEC_CACHE_REDIS_HOST`
|
|
|
|
### 3. Programmatic Configuration
|
|
|
|
```go
|
|
mgr := config.NewManager()
|
|
mgr.Set("server.addr", ":9090")
|
|
mgr.Set("tracing.enabled", true)
|
|
|
|
cfg, _ := mgr.GetConfig()
|
|
```
|
|
|
|
## Configuration Options
|
|
|
|
### Server Configuration
|
|
|
|
```yaml
|
|
server:
|
|
addr: ":8080" # Server address
|
|
shutdown_timeout: 30s # Graceful shutdown timeout
|
|
drain_timeout: 25s # Connection drain timeout
|
|
read_timeout: 10s # HTTP read timeout
|
|
write_timeout: 10s # HTTP write timeout
|
|
idle_timeout: 120s # HTTP idle timeout
|
|
```
|
|
|
|
### Tracing Configuration
|
|
|
|
```yaml
|
|
tracing:
|
|
enabled: false # Enable/disable tracing
|
|
service_name: "resolvespec" # Service name
|
|
service_version: "1.0.0" # Service version
|
|
endpoint: "http://localhost:4318/v1/traces" # OTLP endpoint
|
|
```
|
|
|
|
### Cache Configuration
|
|
|
|
```yaml
|
|
cache:
|
|
provider: "memory" # Options: memory, redis, memcache
|
|
|
|
redis:
|
|
host: "localhost"
|
|
port: 6379
|
|
password: ""
|
|
db: 0
|
|
|
|
memcache:
|
|
servers:
|
|
- "localhost:11211"
|
|
max_idle_conns: 10
|
|
timeout: 100ms
|
|
```
|
|
|
|
### Logger Configuration
|
|
|
|
```yaml
|
|
logger:
|
|
dev: false # Development mode (human-readable output)
|
|
path: "" # Log file path (empty = stdout)
|
|
```
|
|
|
|
### Middleware Configuration
|
|
|
|
```yaml
|
|
middleware:
|
|
rate_limit_rps: 100.0 # Requests per second
|
|
rate_limit_burst: 200 # Burst size
|
|
max_request_size: 10485760 # Max request size in bytes (10MB)
|
|
```
|
|
|
|
### CORS Configuration
|
|
|
|
```yaml
|
|
cors:
|
|
allowed_origins:
|
|
- "*"
|
|
allowed_methods:
|
|
- "GET"
|
|
- "POST"
|
|
- "PUT"
|
|
- "DELETE"
|
|
- "OPTIONS"
|
|
allowed_headers:
|
|
- "*"
|
|
max_age: 3600
|
|
```
|
|
|
|
### Database Configuration
|
|
|
|
```yaml
|
|
database:
|
|
url: "host=localhost user=postgres password=postgres dbname=mydb port=5432 sslmode=disable"
|
|
```
|
|
|
|
## Priority and Overrides
|
|
|
|
Configuration sources are applied in this order (highest priority first):
|
|
|
|
1. **Environment Variables** (highest priority)
|
|
2. **Config File**
|
|
3. **Defaults** (lowest priority)
|
|
|
|
This allows you to:
|
|
- Set defaults in code
|
|
- Override with a config file
|
|
- Override specific values with environment variables
|
|
|
|
## Examples
|
|
|
|
### Production Setup
|
|
|
|
```yaml
|
|
# config.yaml
|
|
server:
|
|
addr: ":8080"
|
|
|
|
tracing:
|
|
enabled: true
|
|
service_name: "myapi"
|
|
endpoint: "http://jaeger:4318/v1/traces"
|
|
|
|
cache:
|
|
provider: "redis"
|
|
redis:
|
|
host: "redis"
|
|
port: 6379
|
|
password: "${REDIS_PASSWORD}"
|
|
|
|
logger:
|
|
dev: false
|
|
path: "/var/log/myapi/app.log"
|
|
```
|
|
|
|
### Development Setup
|
|
|
|
```bash
|
|
# Use environment variables for development
|
|
export RESOLVESPEC_LOGGER_DEV=true
|
|
export RESOLVESPEC_TRACING_ENABLED=false
|
|
export RESOLVESPEC_CACHE_PROVIDER=memory
|
|
```
|
|
|
|
### Testing Setup
|
|
|
|
```go
|
|
// Override config for tests
|
|
mgr := config.NewManager()
|
|
mgr.Set("cache.provider", "memory")
|
|
mgr.Set("database.url", testDBURL)
|
|
|
|
cfg, _ := mgr.GetConfig()
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Use config files for base configuration** - Define your standard settings
|
|
2. **Use environment variables for secrets** - Never commit passwords/tokens
|
|
3. **Use environment variables for deployment-specific values** - Different per environment
|
|
4. **Keep defaults sensible** - Application should work with minimal configuration
|
|
5. **Document your configuration** - Comment your config.yaml files
|
|
|
|
## Integration with ResolveSpec Components
|
|
|
|
The configuration system integrates seamlessly with ResolveSpec components:
|
|
|
|
```go
|
|
cfg, _ := config.NewManager().Load().GetConfig()
|
|
|
|
// Server
|
|
srv := server.NewGracefulServer(server.Config{
|
|
Addr: cfg.Server.Addr,
|
|
ShutdownTimeout: cfg.Server.ShutdownTimeout,
|
|
// ... other fields
|
|
})
|
|
|
|
// Tracing
|
|
if cfg.Tracing.Enabled {
|
|
tracer := tracing.Init(tracing.Config{
|
|
ServiceName: cfg.Tracing.ServiceName,
|
|
ServiceVersion: cfg.Tracing.ServiceVersion,
|
|
Endpoint: cfg.Tracing.Endpoint,
|
|
})
|
|
defer tracer.Shutdown(context.Background())
|
|
}
|
|
|
|
// Cache
|
|
var cacheProvider cache.Provider
|
|
switch cfg.Cache.Provider {
|
|
case "redis":
|
|
cacheProvider = cache.NewRedisProvider(cfg.Cache.Redis.Host, cfg.Cache.Redis.Port, ...)
|
|
case "memcache":
|
|
cacheProvider = cache.NewMemcacheProvider(cfg.Cache.Memcache.Servers, ...)
|
|
default:
|
|
cacheProvider = cache.NewMemoryProvider()
|
|
}
|
|
|
|
// Logger
|
|
logger.Init(cfg.Logger.Dev)
|
|
if cfg.Logger.Path != "" {
|
|
logger.UpdateLoggerPath(cfg.Logger.Path, cfg.Logger.Dev)
|
|
}
|
|
```
|