codeGo

How to Parse JSON in Go

Go's standard library encoding/json package handles all JSON parsing and serialization — no third-party packages needed. This guide covers json.Unmarshal, json.Marshal, struct tags, and error handling.

Parsing JSON with json.Unmarshal

package main

import (
    "encoding/json"
    "fmt"
)

// Define a struct with json tags
type User struct {
    Name   string   `json:"name"`
    Age    int      `json:"age"`
    Active bool     `json:"active"`
    Roles  []string `json:"roles"`
}

func main() {
    jsonStr := `{"name":"Alice","age":30,"active":true,"roles":["admin","editor"]}`

    var user User
    err := json.Unmarshal([]byte(jsonStr), &user)
    if err != nil {
        panic(err) // handle error in production
    }

    fmt.Println(user.Name)     // Alice
    fmt.Println(user.Age)      // 30
    fmt.Println(user.Roles[0]) // admin
}

Parsing Into a Map (No Struct)

jsonStr := `{"name":"Alice","age":30,"score":99.5}`

var result map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &result)
if err != nil {
    panic(err)
}

// Type assertions required
name := result["name"].(string)   // "Alice"
age  := result["age"].(float64)   // JSON numbers → float64
fmt.Println(name, int(age))       // Alice 30

// Parsing a JSON array
jsonArr := `[{"name":"Alice"},{"name":"Bob"}]`
var users []map[string]interface{}
json.Unmarshal([]byte(jsonArr), &users)

Serializing with json.Marshal

user := User{
    Name:   "Alice",
    Age:    30,
    Active: true,
    Roles:  []string{"admin", "editor"},
}

// Compact JSON
data, err := json.Marshal(user)
fmt.Println(string(data))
// {"name":"Alice","age":30,"active":true,"roles":["admin","editor"]}

// Pretty-print
pretty, err := json.MarshalIndent(user, "", "  ")
fmt.Println(string(pretty))

// Useful struct tag options:
type Config struct {
    Host     string `json:"host"`
    Port     int    `json:"port,omitempty"`    // skip if zero
    Password string `json:"-"`                 // never marshal
    Debug    bool   `json:"debug,omitempty"`
}

Error Handling

import (
    "encoding/json"
    "errors"
    "fmt"
)

func parseUser(jsonStr string) (*User, error) {
    var user User
    err := json.Unmarshal([]byte(jsonStr), &user)
    if err != nil {
        var syntaxErr *json.SyntaxError
        var unmarshalErr *json.UnmarshalTypeError

        switch {
        case errors.As(err, &syntaxErr):
            return nil, fmt.Errorf("syntax error at position %d: %w", syntaxErr.Offset, err)
        case errors.As(err, &unmarshalErr):
            return nil, fmt.Errorf("wrong type for field %q: %w", unmarshalErr.Field, err)
        default:
            return nil, err
        }
    }
    return &user, nil
}

Parse JSON in Other Languages

FAQ

How do I parse JSON in Go?expand_more

Use json.Unmarshal() from the standard library encoding/json package. Define a struct with json tags, then: var user User; err := json.Unmarshal([]byte(jsonString), &user). No external packages needed.

What are json struct tags in Go?expand_more

JSON struct tags control how struct fields map to JSON keys. Example: type User struct { Name string `json:"name"` Age int `json:"age"` }. Without tags, Go uses the exact field name (case-sensitive). Tags also support omitempty to skip zero values.

How do I parse JSON into a map in Go?expand_more

Use map[string]interface{}: var result map[string]interface{}; json.Unmarshal([]byte(jsonString), &result). Then access values with type assertions: name := result["name"].(string).

How to Parse JSON in Go – encoding/json Complete Guide