Using JSON with Golang

In this post, we are going to see how to use JSON in the Go programming language.

What is JSON?

JSON is short for JavaScript Object Notation, a widely-used data interchange format. JSON is an extremely useful data format and is used almost everywhere today.

Data-types supported in JSON and Go

Below are some data-types supported in JSON by default in Go. The default types encoded are:

  • bool for boolean data.
  • string for strings.
  • float64 for numbers.
  • nil for null values.

Marshaling Structs to JSON

Marshaling is encoding the data. The JSON package has Marshal function to encode data to JSON. Below is the example showing how to marshal data.

package main

import (
	"fmt"
	"encoding/json"
)

type Book struct {
	Name string
	Author string
}

func main() {
	book := Book{"C++ programming language", "Bjarne Stroutsrup"}
	res, err := json.Marshal(book)
	
	if err != nil {
		fmt.Println(err)
	}
	
	fmt.Println(string(res))      // {"Name":"C++ programming language","Author":"Bjarne Stroutsrup"}
}

Unmarshaling JSON in Go

Unmarshaling is the opposite of marshaling. Here we unpack the JSON to a type in Go. Unmarshaling is decoding.

package main

import (
	"fmt"
	"encoding/json"
)

type Game struct {
	Name string
	Rating float64
}

func main() {
	codString := `{"Name": "Call of Duty", "Rating": 8.4}`
	
	var cod Game
	
	err := json.Unmarshal([]byte(codString), &cod)
	
	if err != nil {
		fmt.Println(err)
	}
	
	fmt.Printf("%+v\n", cod)     // {Name:Call of Duty Rating:8.4}	
}

JSON arrays in Go Programming

JSON arrays can be unmarshaled to the array as well as slice type. We can see the example here how it’s done.

package main

import (
	"fmt"
	"encoding/json"
)

type Software struct {
	Name string
	Developer string
}

func main() {

	softwaresJson := `[{"Name": "AutoCAD","Developer": "Autodesk"},{"Name": "Firefox","Developer": "Mozilla"},{"Name": "Chrome","Developer": "Google"}]`
	
	var softwares []Software
	
	err := json.Unmarshal([]byte(softwaresJson), &softwares)
	
	if err != nil {
		fmt.Println(err)
	}
	
	fmt.Printf("%v\n", softwares)        // [{AutoCAD Autodesk} {Firefox Mozilla} {Chrome Google}]
}

Slice to JSON in Golang

Slices can be converted to JSON easily. We can do it just like the others.

package main

import (
	"fmt"
	"encoding/json"
)

type App struct {
	Name string
}

func main() {
	apps := []App{
		{Name: "Google Play"},
		{Name: "Evernote"},
		{Name: "Buffer"},
	}
	
	appsJson, err := json.Marshal(apps)
	
	if err != nil {
		fmt.Println(err)
	}
	
	fmt.Println(string(appsJson))     // [{"Name":"Google Play"},{"Name":"Evernote"},{"Name":"Buffer"}]
	
}

Set custom attributes in JSON

When working with data in Go, we can set custom attributes for JSON. That will be used when encoding it to JSON instead of the name already given. Here is how we set up custom attributes.

type Book struct {
    Name string `json:"title"`
    Author Author `json:"author"`
}

Unstructured JSON data to Map in Go

Unstructured JSON data can be decoded to a map in Go. In this example, it is shown how to use the map to decode unstructured JSON data.

package main

import (
	"fmt"
	"encoding/json"
)

func main() {
	unstructuredJson := `{"os": {"Windows": "Windows OS","Mac": "OSX","Linux": "Ubuntu"},"compilers": "gcc"}`
	
	var result map[string]interface{}
	
	json.Unmarshal([]byte(unstructuredJson), &result)
	
	fmt.Println(result["os"])    // map[Linux:Ubuntu Mac:OSX Windows:Windows OS]
}

Encoding unstructured data

Encoding unstructured data to JSON can be done using a map. Here’s how we can do that.

package main

import (
	"fmt"
	"encoding/json"
)

type Address struct {
	Street string
	City string
}

type Person struct {
	Name string
	Address Address
}

func main() {
	p := Person{
		Name: "Sherlock Holmes",
		Address: Address{
			"22/b Baker street", 
			"London",
		},
	}
	
	str, err := json.Marshal(p)
	
	if err != nil {
		fmt.Println(err)
	}
	
	fmt.Println(string(str))  // {"Name":"Sherlock Holmes","Address":{"Street":"22/b Baker street","City":"London"}}
}

Ignoring empty fields

There is a flag called omitempty which can be used to skip the part of data if the field is empty. We can use it simply like this.

type book struct {
        Name string `json:"Name"`
        Author string `json:"Author, omitempty"`
}

Skipping fields in JSON

To skip a field in when encoding JSON simply use “-“ as an attribute. It will skip the field from encoding. We can use it like this.

type User struct {
    Name string `json:"Name"`
    Password string `json:"-"`
}

We can see that there is a lot of flexibility in using JSON with Go. It helps write application easily that interacts with an API.