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 JSONjson:"-"— completely excludes the field from JSONjson:"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{}) Also in library
Cobra/pflag for Go: Complete Guide with Examples
Working with Markdown in Swift (iOS/macOS): Down, SwiftMarkdown libraries
Afero Go Guide: File System Abstraction with Examples
Working with Dates in Kotlin: Libraries and Tools (Kotlinx-datetime, Joda-Time, java.time)
Geolocation and Maps in Go: Overview of Libraries and Code Examples