title: "" description: "Reference documentation for Navius " category: "Reference" tags: ["documentation", "reference"] last_updated: "April 3, 2025" version: "1.0"

Configuration Standards

This document outlines the configuration standards and patterns used throughout the Navius framework, providing a reference for consistent configuration implementation.

Configuration File Structure

File Locations

Navius applications use a standardized configuration file structure:

config/
├── default.yaml        # Base configuration (required)
├── development.yaml    # Development environment overrides
├── test.yaml           # Testing environment overrides
└── production.yaml     # Production environment overrides

File Naming Convention

  • default.yaml: Base configuration that applies to all environments
  • {environment}.yaml: Environment-specific overrides (development, test, production)
  • Custom environments can be defined with {custom-name}.yaml

YAML Format Standards

Nesting and Organization

Configuration should be organized in a hierarchical structure:

# Top-level application configuration
app:
  name: "Navius Application"
  version: "1.0.0"
  description: "A Navius framework application"

# Server configuration
server:
  host: "127.0.0.1"
  port: 3000
  timeout_seconds: 30
  
# Feature flags
features:
  advanced_metrics: true
  experimental_api: false
  
# Subsystem configurations
database:
  url: "postgres://localhost:5432/navius"
  max_connections: 10
  timeout_seconds: 5
  
logging:
  level: "info"
  format: "json"
  file: "/var/log/navius.log"

Naming Conventions

  • Use snake_case for all configuration keys
  • Group related settings under common prefixes
  • Use descriptive, clear names
  • Avoid abbreviations unless widely understood

Value Types

  • Strings: Use quotes ("value")
  • Numbers: No quotes (42, 3.14)
  • Booleans: Use true or false (lowercase)
  • Arrays: Use [item1, item2] or multiline list format
  • Maps: Use nested format with indentation

Environment Variables

Environment Variable Mapping

Configuration values can be overridden via environment variables using this pattern:

APP__NAME="Overridden App Name"
SERVER__PORT=8080
FEATURES__ADVANCED_METRICS=false

Rules:

  • Double underscore (__) separates configuration keys
  • Keys are case-insensitive
  • Environment variables take precedence over file configuration

Variable Types

  • Strings: Use as-is
  • Numbers: Parsed from string representation
  • Booleans: true, false, 1, 0, yes, no, y, n (case-insensitive)
  • Arrays: Comma-separated values (val1,val2,val3)
  • Objects: JSON format ({"key": "value"})

Secrets Management

Sensitive Data

Never store secrets in configuration files. Use these approaches instead:

  1. Environment Variables: For most secrets

    DATABASE__PASSWORD="secure-password"
    JWT__SECRET_KEY="jwt-signing-key"
    
  2. External Secret Managers: For advanced scenarios

    secrets:
      provider: "vault"  # or "aws-secrets", "azure-keyvault"
      url: "https://vault.example.com"
      path: "secret/navius"
    
  3. File References: For certificate files

    tls:
      cert_file: "/path/to/cert.pem"
      key_file: "/path/to/key.pem"
    

Secret Configuration Patterns

Use this format for secret references:

database:
  username: "db_user"
  password: "${DB_PASSWORD}"  # Resolved from environment
  
jwt:
  secret: "${JWT_SECRET}"     # Resolved from environment

Configuration Loading

Load Order

Configuration is loaded in this order, with later steps overriding earlier ones:

  1. Default configuration file (default.yaml)
  2. Environment-specific file (based on ENVIRONMENT variable)
  3. Environment variables
  4. Command-line arguments

Command-Line Arguments

Command-line arguments follow this format:

./my-app --server.port=8080 --logging.level=debug

Validation

Schema Validation

All configuration should be validated against a schema:

#![allow(unused)]
fn main() {
#[derive(Debug, Deserialize, Validate)]
pub struct ServerConfig {
    #[validate(required)]
    pub host: String,
    
    #[validate(range(min = 1, max = 65535))]
    pub port: u16,
    
    #[validate(range(min = 1, max = 300))]
    pub timeout_seconds: u32,
}
}

Required vs Optional Settings

Always provide clear documentation about which settings are required vs optional:

# Required settings (no defaults provided by application)
database:
  url: "postgres://localhost:5432/navius"  # REQUIRED
  
# Optional settings (defaults provided by application)
server:
  port: 3000  # Optional, defaults to 3000 if not specified
  host: "127.0.0.1"  # Optional, defaults to 127.0.0.1 if not specified

Feature Flags

Feature Configuration

Organize feature flags under a dedicated section:

features:
  advanced_metrics: true
  experimental_api: false
  beta_endpoints: false
  cache_enabled: true

Feature-Specific Configuration

Group feature-specific settings under the feature name:

features:
  advanced_metrics:
    enabled: true
    sampling_rate: 0.1
    export_interval_seconds: 60
    
  cache:
    enabled: true
    ttl_seconds: 300
    max_entries: 10000

Documentation

Configuration Comments

Include comments in YAML files to document configuration options:

server:
  # The host IP address to bind the server to
  # Use "0.0.0.0" to bind to all interfaces
  host: "127.0.0.1"
  
  # The port number to listen on (1-65535)
  port: 3000
  
  # Request timeout in seconds
  timeout_seconds: 30

Configuration Reference

Maintain a comprehensive configuration reference:

#![allow(unused)]
fn main() {
/// Server configuration options
/// 
/// # Examples
/// 
/// ```yaml
/// server:
///   host: "127.0.0.1"
///   port: 3000
///   timeout_seconds: 30
/// ```
#[derive(Debug, Deserialize)]
pub struct ServerConfig {
    /// The host address to bind to
    pub host: String,
    
    /// The port to listen on (1-65535)
    pub port: u16,
    
    /// Request timeout in seconds
    pub timeout_seconds: u32,
}
}

Default Values

Sensible Defaults

Provide sensible defaults for all optional configuration:

#![allow(unused)]
fn main() {
impl Default for ServerConfig {
    fn default() -> Self {
        Self {
            host: "127.0.0.1".to_string(),
            port: 3000,
            timeout_seconds: 30,
        }
    }
}
}

Overriding Defaults

Document how defaults can be overridden:

# Override defaults in environment-specific files
# development.yaml
server:
  port: 8080  # Override default port

Configuration Update

Dynamic Configuration

For settings that can be updated at runtime:

# Settings that support runtime updates
dynamic:
  logging:
    level: "info"  # Can be changed at runtime
  
  cache:
    ttl_seconds: 300  # Can be changed at runtime

Reload Mechanism

Support configuration reload where appropriate:

#![allow(unused)]
fn main() {
// Reload configuration from disk
config_service.reload().await?;

// Subscribe to configuration changes
config_service.subscribe(|updated_config| {
    // React to changes
});
}

Integration with Services

Dependency Injection

Inject configuration into services:

#![allow(unused)]
fn main() {
// Service that uses configuration
pub struct UserService {
    config: Arc<ConfigService>,
    repository: Arc<UserRepository>,
}

impl UserService {
    pub fn new(
        config: Arc<ConfigService>,
        repository: Arc<UserRepository>,
    ) -> Self {
        Self { config, repository }
    }
    
    pub async fn get_user(&self, id: &str) -> Result<User, Error> {
        let timeout = self.config.get::<u64>("user_service.timeout_seconds")
            .unwrap_or(5);
            
        self.repository.get_user_with_timeout(id, timeout).await
    }
}
}

Best Practices

  1. Centralized Configuration: Keep configuration in one central location
  2. Environment Separation: Use separate files for each environment
  3. Validation: Always validate configuration at startup
  4. Documentation: Document all configuration options
  5. Defaults: Provide sensible defaults for all optional settings
  6. Type Safety: Use strongly-typed configuration objects
  7. Secrets Management: Never store secrets in configuration files
  8. Configuration Testing: Test configuration loading and validation

Example Configuration

Complete Example

# Application configuration
app:
  name: "Navius Example App"
  version: "1.0.0"
  description: "An example Navius application"

# Server configuration
server:
  host: "127.0.0.1"
  port: 3000
  timeout_seconds: 30
  
# Feature flags
features:
  advanced_metrics: true
  experimental_api: false
  
# Database configuration
database:
  driver: "postgres"
  host: "localhost"
  port: 5432
  name: "navius"
  username: "navius_user"
  password: "${DB_PASSWORD}"  # Set via environment variable
  pool:
    max_connections: 10
    timeout_seconds: 5
    idle_timeout_seconds: 300
  
# Logging configuration
logging:
  level: "info"
  format: "json"
  output:
    console: true
    file: "/var/log/navius.log"
  
# Cache configuration
cache:
  enabled: true
  provider: "redis"
  url: "redis://localhost:6379"
  ttl_seconds: 300
  
# Metrics configuration
metrics:
  enabled: true
  exporter: "prometheus"
  endpoint: "/metrics"
  interval_seconds: 15
  
# Health check configuration
health:
  enabled: true
  endpoint: "/health"
  include_details: true
  
# API configuration
api:
  base_path: "/api/v1"
  rate_limit:
    enabled: true
    requests_per_minute: 60
  cors:
    enabled: true
    allowed_origins: ["https://example.com"]