Working with JSON in Go

12.08.2021

Intro

JSON is a domain specific language (DSL) that allows you to defined data. It is an alternative to YAML and is used in many apps to send responses via REST apis to config files. In this article, we will learn how to use JSON in Go.

Getting Started

The "encoding/json" package comes with the Go standard library, so we don't need to install anything.

Let's create an example file called example.json and add the following.

[
    {
        "name": "Jan",
        "salary": 90000
    },
    {
        "name": "Jan",
        "salary": 90000
    }
]

The basic flow is to read the file, the use the Unmarshal function to map our data to a Go type that matches our json file.

Now add some imports to our file.

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

Now, let's create an Employee type to map our data. This should match the entries in our json file.

type Employee struct {
	Name   string
	Salary int
}

First, let's read the file

file, err := ioutil.ReadFile("example.json")

if err != nil {
	log.Fatal(err)
}

Now, let's declare an array of employees that we will read Unmarshal to.

var employees []Employee

err2 := json.Unmarshal(file, &employees)
if err2 != nil {
	log.Fatal(err2)
}

We can then print our data.

for idx, e := range employees {
	fmt.Println(idx, e)
}

Writing to Files

Let's end our json tutorial by learning to write data. We can do this using the Marshal function which does the opposite of above.

users := map[string]Employee{
	"employee1": {"Jan", 90000},
	"employee2": {"Mary", 60000},
}

data, err := yaml.Marshal(&users)

if err != nil {

	log.Fatal(err)
}

err2 := ioutil.WriteFile("users.yaml", data, 0)

if err2 != nil {

	log.Fatal(err2)
}

The Full Example

Here is the full example code. You can run this by copying the contents into a file called main.go and then running go run main.go.

package main

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

type Employee struct {
	Name   string
	Salary int
}

func example() {
	file, err := ioutil.ReadFile("employees.json")
	if err != nil {
		log.Fatal(err)
	}

	var employees []Employee

	err2 := json.Unmarshal(file, &employees)
	if err2 != nil {
		log.Fatal(err2)
	}

	for idx, e := range employees {
		fmt.Println(idx, e)
	}
}

func example2() {
	users := map[string]Employee{
		"employee1": {"Jan", 90000},
		"employee2": {"Mary", 60000},
	}

	data, err := json.Marshal(&users)
	if err != nil {
		log.Fatal(err)
	}

	err2 := ioutil.WriteFile("users.json", data, 0)
	if err2 != nil {
		log.Fatal(err2)
	}
}

func main() {
	example()
	example2()
}