JSON Processing in Go (Golang): Complete Guide with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

JSON Processing in Go (Golang): Complete Guide



Go (Golang) is a modern compiled programming language developed at Google. One of its strengths is built-in support for the JSON format through the standard encoding/json package. Unlike many other languages that require installing third-party libraries, JSON processing in Go is available "out of the box" and offers high performance with strong typing.



In this article, we will thoroughly cover all aspects of working with JSON in Go: from simple parsing to complex scenarios with custom types and streaming processing.



Basics: Encoding and Decoding JSON



The encoding/json package provides two main functions: json.Marshal() for serializing Go structures into JSON and json.Unmarshal() for deserializing JSON back into structures.



Example: Serializing a Structure to JSON



package main

import ( "encoding/json" "fmt")

type User struct { Name string `json:"name"` Age int `json:"age"` Email string `json:"email,omitempty"`}

func main() { user := User{ Name: "Ivan Petrov", Age: 30, Email: "ivan@example.com", }

jsonData, err := json.Marshal(user) if err != nil { fmt.Println("Serialization error:", err) return }

fmt.Println(string(jsonData)) // Output: {"name":"Ivan Petrov","age":30,"email":"ivan@example.com"}}


Example: Deserializing JSON into a Structure



func main() {    jsonString := `{"name":"Anna Smirnova","age":25,"email":"anna@example.com"}`        var user User    err := json.Unmarshal([]byte(jsonString), &user)    if err != nil {        fmt.Println("Deserialization error:", err)        return    }

fmt.Printf("Name: %s, Age: %d, Email: %s", user.Name, user.Age, user.Email)}


Struct Tags



Struct tags in Go allow you to control how fields are serialized into JSON. This is a powerful mechanism for customizing field names, omitting empty values, and other options.



Main tag options:



  • json:"name" — sets the field name in JSON
  • json:"-" — completely excludes the field from JSON
  • json:"name,omitempty" — omits the field if it contains a zero value (0, "", false, nil)
  • json:"name,string" — forces conversion of a numeric field to a string


Example with various tags:



type Product struct {    ID          int     `json:"id"`    Title       string  `json:"title"`    Description string  `json:"description,omitempty"`    Price       float64 `json:"price,string"`    SecretKey   string  `json:"-"`}

func main() { product := Product{ ID: 101, Title: "Laptop", Description: "", Price: 899.99, SecretKey: "sk-12345", }

jsonData, _ := json.MarshalIndent(product, "", " ") fmt.Println(string(jsonData)) // Output: // { // "id": 101, // "title": "Laptop", // "price": "899.99" // }}


Working with Arbitrary JSON Data (interface{})



Sometimes the structure of JSON data is unknown in advance. In such cases, you can use the interface{} type or map[string]interface{}.



func main() {    jsonString := `{"name":"Test","values":[1,2,3],"active":true,"metadata":{"version":2}}`        var data map[string]interface{}    err := json.Unmarshal([]byte(jsonString), &data)    if err != nil {        fmt.Println("Error:", err)        return    }

// Accessing values with type assertions name := data["name"].(string) values := data["values"].([]interface{})

Recommendations