Konfiguration von Rust-Anwendungen: Bibliotheken config und dotenv

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Konfiguration von Rust-Anwendungen: Bibliotheken config und dotenv



Jede moderne Anwendung benötigt ein flexibles Konfigurationssystem: Datenbankeinstellungen, API-Schlüssel, Server-Ports, Logging-Level und andere Parameter. Im Rust-Ökosystem gibt es dafür leistungsstarke Werkzeuge – die Crates config und dotenv. Sie ermöglichen es, Einstellungen aus verschiedenen Quellen (Dateien, Umgebungsvariablen, Kommandozeilenargumente) in einer einzigen typsicheren Struktur zu vereinen.



Warum eine separate Bibliothek?

Rust ist eine Sprache mit starker statischer Typisierung. Das einfache Lesen von Zeichenketten aus std::env::var() führt zu vielen manuellen Prüfungen und Umwandlungen. Die Bibliothek config automatisiert diesen Prozess:

  • Unterstützung von Formaten: YAML, JSON, TOML, HJSON, INI, RON
  • Hierarchische Einstellungsstruktur mit Überschreibungsmöglichkeit
  • Automatische Deserialisierung in benutzerdefinierte Strukturen über serde
  • Zusammenführung mehrerer Quellen mit Prioritäten (Datei < env < CLI)


Installation

Fügen Sie in Cargo.toml hinzu:

[dependencies]config = "0.14"serde = { version = "1.0", features = ["derive"] }dotenv = "0.15"


Basisbeispiel: Lesen aus Datei und env

Erstellen wir eine Struktur für die Anwendungskonfiguration:

use serde::Deserialize;use config::Config;

#[derive(Debug, Deserialize)]struct AppConfig { server: ServerConfig, database: DatabaseConfig,}

#[derive(Debug, Deserialize)]struct ServerConfig { host: String, port: u16, workers: u8,}

#[derive(Debug, Deserialize)]struct DatabaseConfig { url: String, pool_size: u32,}

fn main() -> Result<(), config::ConfigError> { // Konfiguration laden let config = Config::builder() .add_source(config::File::with_name("config/default")) .add_source(config::Environment::with_prefix("APP")) .build()?;

let app_config: AppConfig = config.try_deserialize()?; println!("{:#?}", app_config); Ok(())}


Datei config/default.toml:

[server]host = "127.0.0.1"port = 8080workers = 4

[database]url = "postgres://localhost/mydb"pool_size = 10


Umgebungsvariablen mit dem Präfix APP_ überschreiben die Werte aus der Datei. Beispielsweise ändert APP_DATABASE__URL die Datenbank-URL.



Arbeit mit dotenv

Für die Entwicklung wird oft die Datei .env verwendet. Das Crate dotenv lädt sie in die Umgebungsvariablen, bevor config initialisiert wird:

use dotenv::dotenv;

fn main() { dotenv().ok(); // .env laden // danach Initialisierung von config wie im obigen Beispiel}


Inhalt von .env:

APP_SERVER__PORT=3000APP_DATABASE__POOL_SIZE=20


Fortgeschrittenes Szenario: mehrere Quellen

Reale Projekte erfordern die Kombination von Einstellungen aus verschiedenen Orten. config ermöglicht es, eine Kette von Quellen mit Priorität festzulegen:

let config = Config::builder()    // Basiseinstellungen (niedrige Priorität)    .add_source(config::File::with_name("config/default"))    // Überschreibung für die spezifische Umgebung    .add_source(config::File::with_name(&format!("config/{}", env::var("APP_ENV").unwrap_or("development"))))    // Umgebungsvariablen (mittlere Priorität)    .add_source(config::Environment::with_prefix("APP"))    // Kommandozeilenargumente (hohe Priorität)    .add_source(config::File::from(std::env::args().nth(1).unwrap_or_default()))    .build()?;


Best Practices

  • Verwenden Sie Präfixe für Umgebungsvariablen, um Konflikte mit Systemvariablen zu vermeiden

Empfehlungen