Binding to Structs
Unmarshal config.
Binding to Structs is a free Go Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
From Loose Keys to a Struct
Calling GetString everywhere scatters string keys through your code. Unmarshaling config into a typed struct gives you compile-time field names and one place to see the shape.
Defining a Config Struct
Declare a struct whose fields carry mapstructure tags so Viper knows which config key maps to which field. Each field is followed by a tag such as mapstructure:"host" written between backquotes in real Go source.
type ServerConfig struct {
Host string // tag: mapstructure host
Port int // tag: mapstructure port
}
type Config struct {
Server ServerConfig // tag: mapstructure server
Debug bool // tag: mapstructure debug
}Calling Unmarshal
After reading config, decode it into your struct:
var cfg Config
if err := viper.Unmarshal(&cfg); err != nil {
log.Fatalf("unable to decode config: %v", err)
}
fmt.Println(cfg.Server.Port)Why mapstructure, Not json
Viper uses the mapstructure library because config can come from many formats (YAML, env, TOML), not just JSON. The mapstructure tag is format-agnostic and decodes from a generic map.
Unmarshaling a Single Subtree
You can decode just one section with UnmarshalKey:
var sc ServerConfig
viper.UnmarshalKey("server", &sc)
fmt.Println(sc.Host, sc.Port)Nested and Slice Fields
mapstructure handles nesting and slices automatically:
- Nested structs map to nested config sections
- A
[]stringfield maps to a YAML/JSON array
A slice field would carry a mapstructure:"hosts" tag (written in backquotes in real source).
type Config struct {
Hosts []string // tag: mapstructure hosts
}Default Field Values
If a key is absent and you set no default, the field takes Go's zero value (0, empty string, false). Combine struct binding with SetDefault to guarantee sane values.
Validating the Decoded Struct
After unmarshaling, validate. A common pattern is a Validate() method returning an error for impossible combinations (port 0, empty host).
func (c Config) Validate() error {
if c.Server.Port == 0 {
return fmt.Errorf("server.port is required")
}
return nil
}Decode Errors Are Typed
If a value cannot fit the field type (a string where an int is expected), decoding returns an error describing the field. Always check and surface it rather than ignoring it.
The Same Idea With encoding/json
The standard library can decode JSON the same way. With explicit struct tags it fills typed fields; with a map it gives you generic access. The runnable below uses a nested map so the player can execute it without struct tags.
Runnable: Decode Nested Config
This self-contained program decodes nested JSON config into a generic map and reads the nested fields, mirroring how Unmarshal populates a struct.
package main
import (
"encoding/json"
"fmt"
)
func main() {
raw := "{\"server\":{\"host\":\"localhost\",\"port\":8080},\"debug\":true}"
var c map[string]any
if err := json.Unmarshal([]byte(raw), &c); err != nil {
panic(err)
}
srv := c["server"].(map[string]any)
fmt.Printf("%v:%v debug=%v\n", srv["host"], srv["port"], c["debug"])
}Quick Check
Test your understanding of binding config to structs.
Recap
You learned to bind config into structs:
- Use
mapstructuretags andviper.Unmarshal(&cfg) UnmarshalKeydecodes a single subtree- Nested structs and slices decode automatically
- Add a
Validate()method to catch bad combinations early
Frequently asked questions
Is the “Binding to Structs” lesson free?
Yes — the full text of “Binding to Structs” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.
What will I learn in “Binding to Structs”?
Unmarshal config. You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Go Academy?
No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Binding to Structs” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Go Academy lesson?
Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Reading Config Files
- Environment Variables
- Defaults and Watching
- Binding to Structs