JSON Processing in Go (Golang): encoding/json and Alternatives

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): From Basics to Advanced Techniques



Go (Golang) offers a powerful and intuitive set of tools for working with JSON. The standard library encoding/json covers 95% of tasks, and for high-load projects, there are more performant alternatives. In this article, we will cover all aspects of JSON processing in Go: from basic serialization to custom parsers and optimization.



1. Basics: The Standard Library encoding/json



In Go, JSON is processed through the encoding/json package. The main operations are marshaling (serialization to JSON) and unmarshaling (deserialization from JSON).



1.1. Marshaling (struct → JSON)



To convert a Go struct to JSON, use the json.Marshal() function:



package main

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

type User struct { Name string `json:"name"` Age int `json:"age"` Email string `json:"email,omitempty"` // omitempty - skip if empty}

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

jsonData, err := json.Marshal(user) if err != nil { log.Fatal(err) }

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


Important: Struct fields must be exported (start with a capital letter). The json:"fieldname" tags control the field names in JSON.



1.2. Unmarshaling (JSON → struct)



For the reverse transformation, use json.Unmarshal():



func main() {    jsonString := `{"name":"Anna","age":25,"email":"anna@mail.com"}`        var user User    err := json.Unmarshal([]byte(jsonString), &user)    if err != nil {        log.Fatal(err)    }

fmt.Printf("Name: %s, Age: %d", user.Name, user.Age) // Name: Anna, Age: 25}


2. Working with Nested Structures and Arrays



JSON often contains nested objects and arrays. In Go, this maps to nested structs and slices:



type Address struct {    City    string `json:"city"`    Street  string `json:"street"`    ZipCode string `json:"zip_code"`}

type Company struct { Name string `json:"name"` Employees []User `json:"employees"` Address Address `json:"address"`}

func main() { companyJSON := `{ "name": "TechCorp", "employees": [ {"name":"Oleg","age":28,"email":"oleg@tech.com"}, {"name":"Maria","age":32,"email":"maria@tech.com"} ], "address": { "city": "Moscow", "street": "Tverskaya, 10", "zip_code": "101000" } }`

var company Company json.Unmarshal([]byte(companyJSON), &company) fmt.Printf("Company: %s, City: %s, Employees: %d", company.Name, company.Address.City, len(company.Employees))}


3. Advanced Techniques



3.1. Custom Serialization (Marshaler/Unmarshaler Interfaces)



Sometimes you need to control how a type is converted to JSON. To do this, implement the json.Marshaler and json.Unmarshaler interfaces:



type CustomTime struct {    time.Time}

const layout = "2006-01-02T15:04:05Z"

func (ct CustomTime) MarshalJSON() ([]byte, error) { return json.Marshal(ct.Format(layout))}

func (ct *CustomTime) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } t, err := time.Parse(layout, s) if err != nil { return err } ct.Time = t return nil}

type Event struct { Title string `json:"title"` Date CustomTime `js

Recommendations