Go:
Working with JSON

How to:

In Go, the encoding/json package is your gateway to JSON manipulation, providing mechanisms to convert Go data structures to JSON (marshalling) and back (unmarshalling). Below are basic examples to get you started:

Encoding (Marshalling)

To convert a Go struct to JSON, you can use json.Marshal. Consider the following Go struct:

package main

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

type User struct {
    ID        int      `json:"id"`
    Username  string   `json:"username"`
    Languages []string `json:"languages"`
}

func main() {
    user := User{1, "JohnDoe", []string{"Go", "JavaScript", "Python"}}
    userJSON, err := json.Marshal(user)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(userJSON))
}

Output:

{"id":1,"username":"JohnDoe","languages":["Go","JavaScript","Python"]}

Decoding (Unmarshalling)

To parse JSON into a Go data structure, use json.Unmarshal:

package main

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

func main() {
    jsonStr := `{"id":1,"username":"JohnDoe","languages":["Go","JavaScript","Python"]}`
    var user User
    err := json.Unmarshal([]byte(jsonStr), &user)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%+v\n", user)
}

Given struct User as before, this code parses the JSON string into a User instance.

Output:

{ID:1 Username:JohnDoe Languages:[Go JavaScript Python]}

Deep Dive

The encoding/json package in Go offers a straightforward API that abstracts much of the complexity involved in JSON manipulation. Introduced early in Go’s development, this package reflects Go’s philosophy of simplicity and efficiency. However, the use of reflection by encoding/json to inspect and modify structs at runtime can lead to less than optimal performance in CPU-intensive scenarios.

Alternatives like json-iterator/go and ffjson have emerged, providing faster JSON processing by generating static marshalling and unmarshalling code. However, encoding/json remains the most commonly used package due to its simplicity, robustness, and the fact that it’s part of the standard library, ensuring compatibility and stability across Go versions.

Despite its slower relative performance, the ease of use and the integration with Go’s type system make encoding/json suitable for most applications. For those working in contexts where performance is paramount, exploring external libraries may be worthwhile, but for many, the standard library strikes the right balance between speed, simplicity, and reliability.