JSON in go

JSON (JavaScript Object Notation) is a lightweight data format used to store and exchange data between a client and a server.
Go provides the encoding/json
package to easily work with JSON data.
Marshalling:
package main
import (
"encoding/json"
"fmt"
"log"
"time"
"os"
)
func main() {
// Marshalling
myMap := map[string]interface{}{
"name": "John",
"Class": 9,
"over18": false,
"subjects": map[string]interface{}{
"marks": []int{23, 23, 44, 43},
},
}
jsonData, err := json.Marshal(myMap)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonData))
}
Adding Time :
You can also store the current time in JSON. Go will convert it into a proper format.
//Using time
myTimeMap := map[string]interface{}{
"TimeNow": time.Now(),
}
jsonTimeData, err := json.Marshal(myTimeMap)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonTimeData))
Struct without JSON tags :
When using structs without tags, Go uses field names as JSON keys. But note:
The field must start with a capital letter to be exported (visible for JSON encoding).
// Using Struct with no Json tags
type Student struct { //remember the struct to be decoded or encoded should be exported
Name string
Class int
Over18 bool
Marks []int
}
S1 := &Student{
Name: "John",
Class: 9,
Over18: false,
Marks: []int{22, 34, 42, 40},
}
jsonStructData, err := json.Marshal(S1)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonStructData))
Struct with JSON tags :
Adding JSON tags lets you control the key names in the final JSON. For example:
Over18
field will appear as"over18"
in JSON.
//using structs with explicit json tags
type NewStudent struct { //remember the struct to be decoded or encoded should be exported
Name string `json:"name"`
Class int `json:"class"`
Over18 bool `json:"over18"`
Marks []int `json:"marks"`
}
S2 := &NewStudent{
Name: "John",
Class: 9,
Over18: false,
Marks: []int{22, 34, 42, 40},
}
jsonStructWTData, err := json.Marshal(S2)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonStructWTData))
Using omitempty
to hide empty fields :
If the Marks
slice is nil
or empty, it will be skipped from the JSON output. This keeps the output clean.
// using omit empty for omitting empty fields
type NewStudent1 struct { //remember the struct to be decoded or encoded should be exported
Name string `json:"name"`
Class int `json:"class"`
Over18 bool `json:"over18"`
Marks []int `json:"marks,omitempty"`
}
S3 := &NewStudent1{
Name: "John",
Class: 9,
Over18: false,
Marks: nil,
}
jsonStructWTData, err = json.Marshal(S3)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonStructWTData))
Decoding JSON into a map[string]interface{}
:
Unmarshal
is the opposite of Marshal.
Unmarshal = Convert JSON → Go
// Parsing JSON data into map
jsondata :=
`{
"name":"John",
"class": 9,
"over18": false,
"marks":[22,34,54,65]
}`
var anotherMap map[string] interface{}
err = json.Unmarshal([]byte(jsondata), &anotherMap)
if err != nil {
log.Fatal(err)
}
fmt.Println(anotherMap)
Decoding JSON into a struct :
It converts the JSON into a proper Go struct.
// Parsing json into struct
var myStruct NewStudent
err = json.Unmarshal([]byte(jsondata), &myStruct)
if err != nil {
log.Fatal(err)
}
fmt.Println(myStruct)
Writing JSON to Stdout using Encoder
:
Instead of printing JSON manually, you can directly encode and write it to the terminal (or any output stream) using an Encoder
.
// encoding struct data to json and writing it to stdout
enc := json.NewEncoder(os.Stdout)
enc.Encode(S2)
Reading JSON from a file using Decoder
:
// decoding json data from a file "ex.json" to a struct
file, _ := os.Open("ex.json")
defer file.Close()
dec := json.NewDecoder(file)
dec.Decode(&myStruct)
fmt.Println(myStruct)
complete code:
package main
import (
"encoding/json"
"fmt"
"log"
"time"
"os"
)
func main() {
// Marshalling
myMap := map[string]interface{}{
"name": "John",
"Class": 9,
"over18": false,
"subjects": map[string]interface{}{
"marks": []int{23, 23, 44, 43},
},
}
jsonData, err := json.Marshal(myMap)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonData))
//Using time
myTimeMap := map[string]interface{}{
"TimeNow": time.Now(),
}
jsonTimeData, err := json.Marshal(myTimeMap)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonTimeData))
// Using Struct with no Json tags
type Student struct { //remember the struct to be decoded or encoded should be exported
Name string
Class int
Over18 bool
Marks []int
}
S1 := &Student{
Name: "John",
Class: 9,
Over18: false,
Marks: []int{22, 34, 42, 40},
}
jsonStructData, err := json.Marshal(S1)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonStructData))
//using structs with explicit json tags
type NewStudent struct { //remember the struct to be decoded or encoded should be exported
Name string `json:"name"`
Class int `json:"class"`
Over18 bool `json:"over18"`
Marks []int `json:"marks"`
}
S2 := &NewStudent{
Name: "John",
Class: 9,
Over18: false,
Marks: []int{22, 34, 42, 40},
}
jsonStructWTData, err := json.Marshal(S2)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonStructWTData))
// using omit empty for omitting empty fields
type NewStudent1 struct { //remember the struct to be decoded or encoded should be exported
Name string `json:"name"`
Class int `json:"class"`
Over18 bool `json:"over18"`
Marks []int `json:"marks,omitempty"`
}
S3 := &NewStudent1{
Name: "John",
Class: 9,
Over18: false,
Marks: nil,
}
jsonStructWTData, err = json.Marshal(S3)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonStructWTData))
// Parsing JSON data into map
jsondata :=
`{
"name":"John",
"class": 9,
"over18": false,
"marks":[22,34,54,65]
}`
var anotherMap map[string] interface{}
err = json.Unmarshal([]byte(jsondata), &anotherMap)
if err != nil {
log.Fatal(err)
}
fmt.Println(anotherMap)
// Parsing json into struct
var myStruct NewStudent
err = json.Unmarshal([]byte(jsondata), &myStruct)
if err != nil {
log.Fatal(err)
}
fmt.Println(myStruct)
// encoding struct data to json and writing it to stdout
enc := json.NewEncoder(os.Stdout)
enc.Encode(S2)
// decoding json data from a file "ex.json" to a struct
file, _ := os.Open("ex.json")
defer file.Close()
dec := json.NewDecoder(file)
dec.Decode(&myStruct)
fmt.Println(myStruct)
}
Output :
{"Class":9,"name":"John","over 18":false,"subjects":{"marks":[23,23,44,43]}}
{"TimeNow":"2025-08-02T20:15:10.8961321+05:30"}
{"Name":"John","Class":9,"Over18":false,"Marks":[22,34,42,40]}
{"name":"John","class":9,"over18":false,"marks":[22,34,42,40]}
{"name":"John","class":9,"over18":false}
map[class:9 marks:[22 34 54 65] name:John over18:false]
{John 9 false [22 34 54 65]}
{"name":"John","class":9,"over18":false,"marks":[22,34,42,40]}
{John 9 true [22 34 54 65]}
There is much more to explore in encoding/json
, I will try to update this blog, as I discover and learn new things.
Subscribe to my newsletter
Read articles from Priyansh Sao directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
