Robust Configuration Management in Go
Configuration management is crucial for any application, allowing you to adapt behavior without modifying code. This challenge asks you to build a simple configuration management system in Go that loads settings from a YAML file, handles missing values gracefully, and provides a clean interface for accessing configuration parameters. This is a common task in real-world Go applications, enabling flexibility and maintainability.
Problem Description
You are tasked with creating a Config struct and associated functions to load and access configuration settings from a YAML file. The configuration file will contain key-value pairs, where values can be strings, integers, or booleans. Your solution should:
- Load Configuration: Implement a function
LoadConfig(filePath string) (*Config, error)that reads a YAML file from the givenfilePathand parses it into aConfigstruct. Use a suitable YAML parsing library (e.g.,gopkg.in/yaml.v2). ConfigStruct: Define aConfigstruct that holds the configuration settings. It should include fields for:AppName(string): The name of the application.Port(int): The port number to listen on.DebugMode(bool): Whether the application should run in debug mode.DatabaseURL(string): The database connection string.
- Error Handling: The
LoadConfigfunction should return an error if the file cannot be opened, read, or parsed. - Default Values: If a configuration setting is missing from the YAML file, use sensible default values. These defaults should be:
AppName: "MyApplication"Port: 8080DebugMode: falseDatabaseURL: "localhost:5432"
- Accessors: Provide getter methods (e.g.,
GetAppName(),GetPort(),GetDebugMode(),GetDatabaseURL()) for accessing the configuration values from theConfigstruct. These methods should return the configured values or the default values if the configuration is not set.
Examples
Example 1:
Input YAML (config.yaml):
appName: MyApp
port: 9000
debugMode: true
// Expected Output (after calling LoadConfig("config.yaml")):
// Config{AppName: "MyApp", Port: 9000, DebugMode: true, DatabaseURL: "localhost:5432"}
Explanation: The YAML file provides values for AppName, Port, and DebugMode. DatabaseURL is not present, so it uses the default value.
Example 2:
Input YAML (config.yaml):
port: 80
// Expected Output (after calling LoadConfig("config.yaml")):
// Config{AppName: "MyApplication", Port: 80, DebugMode: false, DatabaseURL: "localhost:5432"}
Explanation: Only Port is specified in the YAML file. The other fields use their default values.
Example 3: (Edge Case - Invalid YAML)
Input YAML (config.yaml):
appName: MyApp
port: abc # Invalid port value
// Expected Output (after calling LoadConfig("config.yaml")):
// error: YAML parsing error: ... (details of the parsing error)
Explanation: The YAML file contains an invalid value for Port. The LoadConfig function should return an error.
Constraints
- The YAML file path will be a string.
- The YAML file will contain valid YAML syntax (though values might be missing or invalid).
- The
Portvalue must be an integer between 1 and 65535 (inclusive). If the YAML file contains a port value outside this range, treat it as if it were missing and use the default value. - The YAML parsing library should be
gopkg.in/yaml.v2. - The solution should be well-structured and readable.
Notes
- Consider using error handling best practices (e.g., returning errors explicitly, checking for errors after each operation).
- Think about how to handle potential errors during YAML parsing (e.g., invalid data types).
- The getter methods should provide a clean and consistent interface for accessing configuration values.
- You don't need to implement file creation or modification; only loading from an existing file is required.
- Focus on the core functionality of loading and accessing configuration settings. Advanced features like validation or environment variable overrides are not required for this challenge.