Go - Advanced Configuration
Beginner 10/10
Teacher 10/10
Architect 10/10
Advanced Configuration
Design a predictable config system: defaults < strong < files < env < flags. Validate and log effective config on startup (without secrets).
Try it: Implement precedence and print the final config as JSON.
Pattern
type Config struct{ Port int; Env, DSN string }
func Load(path string, args []string) (Config, error) {
c := Config{Port:8080, Env:"dev"}
// file (JSON)
if path != "" { b, err := os.ReadFile(path); if err==nil { json.Unmarshal(b, &c) } }
// env
if v := os.Getenv("PORT"); v != "" { if p, _ := strconv.Atoi(v); p>0 { c.Port = p } }
if v := os.Getenv("ENV"); v != "" { c.Env = v }
if v := os.Getenv("DSN"); v != "" { c.DSN = v }
// flags
fs := flag.NewFlagSet("app", flag.ContinueOnError)
port := fs.Int("port", c.Port, "port")
env := fs.String("env", c.Env, "env")
dsn := fs.String("dsn", c.DSN, "db dsn")
_ = fs.Parse(args)
c.Port, c.Env, c.DSN = *port, *env, *dsn
return c, nil
}
Common errors
- Dumping secrets in logs—redact or omit sensitive fields when printing config.
- Allowing invalid configs—add validation (e.g., port range, DSN required in prod).
Practice
- Add validation and return errors for missing required values in production.
Quick quiz
- What precedence order prevents surprises?