Simplify JSON Handling in Go: From Maps to Structs and Powerful Libraries

This article explains why processing JSON in a statically‑typed language like Go can be cumbersome, demonstrates two basic approaches—using map[string]interface{} and struct tags—highlights their limitations, and introduces third‑party libraries such as SJSON and GJSON that make JSON reading and writing more concise and efficient.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Simplify JSON Handling in Go: From Maps to Structs and Powerful Libraries

My first Go project needed to process a collection of JSON test fixtures and pass the data to an API. In dynamically typed languages JSON is easy to parse, but in statically typed languages you must define how to handle strings, numbers, maps and arrays.

Parsing/Serializing to map[string]interface{}

Example program:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    byt := []byte(`{
        "num":6.13,
        "strs":["a","b"],
        "obj":{"foo":{"bar":"zip","zap":6}}
    }`)
    var dat map[string]interface{}
    if err := json.Unmarshal(byt, &dat); err != nil {
        panic(err)
    }
    fmt.Println(dat)
    num := dat["num"].(float64)
    fmt.Println(num)
    strs := dat["strs"].([]interface{})
    str1 := strs[0].(string)
    fmt.Println(str1)
    obj := dat["obj"].(map[string]interface{})
    obj2 := obj["foo"].(map[string]interface{})
    fmt.Println(obj2)
}

The JSON is unmarshaled into a map[string]interface{}. Accessing nested values requires type assertions, which becomes cumbersome for deeply nested structures.

Parsing/Serializing to struct

Using a struct with JSON tags:

package main

import (
    "encoding/json"
    "fmt"
)

type ourData struct {
    Num   float64                       `json:"num"`
    Strs []string                       `json:"strs"`
    Obj   map[string]map[string]string `json:"obj"`
}

func main() {
    byt := []byte(`{
        "num":6.13,
        "strs":["a","b"],
        "obj":{"foo":{"bar":"zip","zap":6}}
    }`)
    var res ourData
    json.Unmarshal(byt, &res)
    fmt.Println(res.Num)
    fmt.Println(res.Strs)
    fmt.Println(res.Obj)
}

Struct tags let the encoding/json package map JSON fields to struct fields, reducing the need for explicit type assertions. However, tags only apply to top‑level fields, nested objects still require complex types, and any extra JSON fields (e.g., "zap") are ignored unless the struct defines them.

When json.Unmarshal deserializes JSON into this struct, the top‑level num member is assigned to Num .

These approaches are still limited: they don’t handle changing JSON schemas well and nested structures remain verbose.

SJSON and GJSON

Third‑party packages provide more concise handling. SJSON (for writing) and GJSON (for reading) were created by Josh Baker.

package main

import "github.com/tidwall/gjson"

const JSON = `{"name":{"first":"Janet","last":"Prichard"},"age":47}`

func main() {
    value := gjson.Get(JSON, "name.last")
    println(value.String())
}

GJSON extracts nested values with a simple path expression.

package main

import "github.com/tidwall/sjson"

const JSON = `{"name":{"first":"Janet","last":"Prichard"},"age":47}`

func main() {
    value, _ := sjson.Set(JSON, "name.last", "Anderson")
    println(value)
}

Other libraries such as ffjson, easyjson, and gabs also offer alternative JSON handling strategies.

Source: https://alanstorm.com/simplified-json-handling-in-go/

References

Go example tutorial: https://gobyexample.com/json

Type assertions: https://www.sohamkamani.com/golang/type-assertions-vs-type-conversions/

Back‑ticks in Go: https://golangbyexample.com/double-single-back-quotes-go/

Reflection API: https://pkg.go.dev/reflect

Accessing struct tags: https://stackoverflow.com/questions/23507033/get-struct-field-tag-using-go-reflect-package/23507821#23507821

SJSON: https://github.com/tidwall/sjson

GJSON: https://github.com/tidwall/gjson

Josh Baker: https://github.com/tidwall

ffjson: https://github.com/pquerna/ffjson

easyjson: https://github.com/mailru/easyjson

gabs: https://github.com/Jeffail/gabs

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendserializationJSONstructgjsonsjson
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.