Files
2025-11-17 23:25:36 +09:00

130 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Working with JSON
Lets learn how to work with JSON data.
The Go standard library includes `encoding/json`, which is for working with JSON data. Additionally, Go allows us to add support for JSON fields in Go structures using tags. Tags control the encoding and decoding of JSON records to and from Go structures. But first, we should talk about marshaling and unmarshaling JSON records.
## Using `Marshal()` and `Unmarshal()`
Both the marshaling and unmarshaling of JSON data are important procedures for working with JSON data using Go structures. **Marshaling** is the process of converting a Go structure into a JSON record. We usually want that for transferring JSON data via computer networks or for saving it on disk. **Unmarshaling** is the process of converting a JSON record given as a byte slice into a Go structure. We usually want that when receiving JSON data via computer networks or when loading JSON data from disk files.
> **Note:** The number one bug when converting JSON records into Go structures and vice versa is not making the required fields of our Go structures exported. When we have issues with marshaling and unmarshaling, begin our debugging process from there.
# Coding example
The code in `encodeDecode.go` illustrates both the marshaling and unmarshaling of JSON records using hardcoded data for simplicity:
```go
package main
import (
"encoding/json"
"fmt"
)
type UseAll struct {
Name string `json:"username"`
Surname string `json:"surname"`
Year int `json:"created"`
}
```
What the previous metadata tells us is that the `Name` field of the `UseAll` structure is translated to `username` in the JSON record, and vice versa; the `Surname` field is translated to `surname`, and vice versa; and the `Year` structure field is translated to `created` in the JSON record, and vice versa. This information has to do with the marshaling and unmarshaling of JSON data. Other than this, we treat and use `UseAll` as a regular Go structure.
```go
func main() {
useall := UseAll{Name: "Mike", Surname: "Tsoukalos", Year: 2021}
// Regular Structure
// Encoding JSON data -> Convert Go Structure to JSON record with fields
t, err := json.Marshal(&useall)
}
```
The `json.Marshal()` function requires a pointer to a structure variable—its real data type is an empty interface variable—and returns a byte slice with the encoded information and an `error` variable.
```go
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Value %s\n", t)
}
// Decoding JSON data given as a string
str := `{"username": "M.", "surname": "Ts", "created":2020}`
```
JSON data usually comes as a string.
```go
// Convert string into a byte slice
jsonRecord := []byte(str)
```
However, as `json.Unmarshal()` requires a byte slice, we need to convert that string into a byte slice before passing it to `json.Unmarshal()`.
```go
// Create a structure variable to store the result
temp := UseAll{}
err = json.Unmarshal(jsonRecord, &temp)
```
The `json.Unmarshal()` function requires the byte slice with the JSON record and a pointer to the Go structure variable that is going to store the JSON record and returns an `error` variable.
```go
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Data type: %T with value %v\n", temp, temp)
}
```
Running `encodeDecode.go` produces the next output:
```bash
# go run encodeDecode.go
Value {"username":"Mike","surname":"Tsoukalos","created":2021}
Data type: main.UseAll with value {M. Ts 2020}
```
```go
package main
import (
"encoding/json"
"fmt"
)
type UseAll struct {
Name string `json:"username"`
Surname string `json:"surname"`
Year int `json:"created"`
}
func main() {
useall := UseAll{Name: "Mike", Surname: "Tsoukalos", Year: 2021}
// Regular Structure
// Encoding JSON data -> Convert Go Structure to JSON record with fields
t, err := json.Marshal(&useall)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Value %s\n", t)
}
// Decoding JSON data given as a string
str := `{"username": "M.", "surname": "Ts", "created":2020}`
// Convert string into a byte slice
jsonRecord := []byte(str)
// Create a structure variable to store the result
temp := UseAll{}
err = json.Unmarshal(jsonRecord, &temp)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Data type: %T with value %v\n", temp, temp)
}
}
```