JSON (JavaScript Object Notation) is a popular format for exchanging data between a client and a server. In Go, working with JSON strings is straightforward thanks to the encoding/json package, which provides various methods to marshal and unmarshal JSON data.
Table of Contents
Basic Usage: Encoding and Decoding JSON
In the most basic form, you can encode Go data structures to JSON and decode JSON back to Go data structures.
Encoding (Marshalling) Go Struct to JSON
package main
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"`
Email string `json:"email"`
Age int `json:"age"`
}
func main() {
user := User{
Name: "Alice",
Email: "[email protected]",
Age: 30,
}
jsonData, err := json.Marshal(user)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(jsonData)) // Output: {"name":"Alice","email":"[email protected]","age":30}
}
Decoding (Unmarshalling) JSON to Go Struct
package main
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"`
Email string `json:"email"`
Age int `json:"age"`
}
func main() {
jsonString := `{"name":"Bob","email":"[email protected]","age":25}`
var user User
err := json.Unmarshal([]byte(jsonString), &user)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%+v\n", user) // Output: {Name:Bob Email:[email protected] Age:25}
}
Intermediate Usage: Working with JSON Data Without Defined Structs
You can also work with arbitrary JSON data without defining a struct using interface{} and type assertions.
Decoding JSON to Map
package main
import (
"encoding/json"
"fmt"
)
func main() {
jsonString := `{"title":"Gopher","tags":["go","programming"]}`
var result map[string]interface{}
json.Unmarshal([]byte(jsonString), &result)
fmt.Println(result["title"]) // Output: Gopher
fmt.Println(result["tags"].([]interface{})[0]) // Output: go
}
Advanced Usage: Handling JSON with Custom Unmarshalling
Sometimes, JSON structures are not straightforward and might require custom unmarshalling logic to populate Go structs.
Custom Unmarshalling with Example
package main
import (
"encoding/json"
"fmt"
)
type ComplexUser struct {
Name string
Attributes map[string]string
}
func (cu *ComplexUser) UnmarshalJSON(data []byte) error {
var tempStruct struct {
Name string `json:"name"`
Attributes map[string]interface{} `json:"attributes"`
}
if err := json.Unmarshal(data, &tempStruct); err != nil {
return err
}
cu.Name = tempStruct.Name
cu.Attributes = make(map[string]string)
for k, v := range tempStruct.Attributes {
if str, ok := v.(string); ok {
cu.Attributes[k] = str
}
}
return nil
}
func main() {
jsonString := `{"name":"Charlie","attributes":{"nickname":"Char","hobby":"Books"}}`
var user ComplexUser
json.Unmarshal([]byte(jsonString), &user)
fmt.Printf("%+v\n", user) // Output: {Name:Charlie Attributes:map[hobby:Books nickname:Char]}
}
By following these steps, you can manage simple and complex JSON data within your Go applications effectively.