Settings
Load typed application settings from environment variables using Zigmund's settings infrastructure. Define a schema of expected settings, load them from the environment, and access them with type-safe getters.
Overview
Application configuration should be externalized from code. Zigmund provides SettingSpec to define expected environment variables, loadSettingsFromEnvMap to load and validate them, and typed accessors like getBool() and getInt() to retrieve values with automatic type conversion.
This is the Zig equivalent of FastAPI/Pydantic's BaseSettings pattern for environment-based configuration.
Example
const std = @import("std");
const zigmund = @import("zigmund");
fn readSettings(req: *zigmund.Request, allocator: std.mem.Allocator) !zigmund.Response {
_ = req;
var env_map = std.process.EnvMap.init(allocator);
defer env_map.deinit();
try env_map.put("APP_NAME", "zigmund");
try env_map.put("FEATURE_BETA", "true");
try env_map.put("PORT", "9001");
const specs = [_]zigmund.SettingSpec{
.{ .key = "app_name", .env = "APP_NAME" },
.{ .key = "feature_beta", .env = "FEATURE_BETA" },
.{ .key = "port", .env = "PORT" },
.{ .key = "environment", .env = "ENVIRONMENT", .required = false, .default_value = "dev" },
};
var settings = try zigmund.loadSettingsFromEnvMap(allocator, &specs, &env_map);
defer settings.deinit();
return zigmund.Response.json(allocator, .{
.app_name = settings.get("app_name").?,
.feature_beta = try settings.getBool("feature_beta"),
.port = try settings.getInt(u16, "port"),
.environment = settings.get("environment").?,
});
}
pub fn buildExample(app: *zigmund.App) !void {
try app.get("/settings", readSettings, .{
.summary = "Load typed settings from environment",
});
}
How It Works
1. Defining Setting Specifications
Create an array of SettingSpec structs that describe each expected setting:
const specs = [_]zigmund.SettingSpec{
.{ .key = "app_name", .env = "APP_NAME" },
.{ .key = "port", .env = "PORT" },
.{ .key = "environment", .env = "ENVIRONMENT", .required = false, .default_value = "dev" },
};
Each SettingSpec has the following fields:
| Field | Type | Description |
|---|---|---|
key |
[]const u8 |
Internal key used to retrieve the setting. |
env |
[]const u8 |
Environment variable name to read from. |
required |
bool |
Whether the variable must be set. Default: true. |
default_value |
?[]const u8 |
Fallback value when the variable is not set. |
2. Loading Settings
Load settings from an environment map:
var settings = try zigmund.loadSettingsFromEnvMap(allocator, &specs, &env_map);
defer settings.deinit();
In production, the environment map comes from std.process.getEnvMap() or similar. The example uses a manually constructed EnvMap for demonstration.
If a required setting is missing and has no default_value, loadSettingsFromEnvMap returns an error.
3. Accessing Settings as Strings
Use settings.get(key) to retrieve a setting as an optional string:
const app_name = settings.get("app_name").?;
4. Typed Accessors
Convert settings to specific types with typed getters:
const port = try settings.getInt(u16, "port"); // Parse as u16
const beta = try settings.getBool("feature_beta"); // Parse as bool
These return an error if the value cannot be parsed as the requested type.
5. Optional Settings with Defaults
Mark a setting as optional with .required = false and provide a .default_value:
.{ .key = "environment", .env = "ENVIRONMENT", .required = false, .default_value = "dev" },
If ENVIRONMENT is not set, settings.get("environment") returns "dev".
Key Points
SettingSpecdefines a schema for environment-based configuration.loadSettingsFromEnvMapvalidates required settings and applies defaults.- Use
settings.get()for string values,settings.getInt()for integers, andsettings.getBool()for booleans. - Required settings without defaults cause an error if the environment variable is not set.
- Always call
defer settings.deinit()to release allocated memory. - Load settings in a startup hook or at application initialization for early validation.
See Also
- Events -- load settings in a startup hook.
- Behind a Proxy -- configure proxy settings from environment variables.
- Advanced Dependencies -- inject settings as dependencies.