🦉
Programming Notes
  • My Programming Notes
  • CKA Exam Preparation
    • Certified Kubernetes Administrator
    • Setup Minikube
    • Network Design Principles
    • Role-Based Access Control (RBAC)
    • Namespace
    • Resource Quota
    • Pod
    • Deployment
    • Deployment: Rollout
    • ConfigMap
    • Service
    • Service: kubectl expose
    • Pod: Resources Management
    • Pod & Container: Quality of Service Class
    • Pod & Container: Probes
    • Limit Range
    • Scaling: Manual
    • Scaling: Horizontal Pod Autoscaler
    • Persistent Volume & Claim
    • Secret
    • Ingress: Routing
    • Ingress: TLS
    • Ingress: Rate Limit
    • Ingress: Basic Auth
    • Ingress: CRD (Custom Resource Definition)
    • Job
    • CronJob
    • Mutli-Node Cluster
  • Golang
    • Generics
    • Context
    • Goroutines and Channels in Go
    • Goroutine: Concurrency vs Parallelism
    • Goroutine: Performance & Tradeoffs
    • JSON: omitzero
  • Rust
    • Arrays & Slices
    • Closures
    • Generics & Traits
    • Iterators
    • Run Code Simultaneously
    • String vs &str
    • Tests
    • Rustlings Exercises
      • Variables
      • Functions
      • If
      • Primitive Types
      • Vectors
      • Move Semantics
      • Structs
      • Enums and Matching Pattern
      • Strings
      • Modules
      • Hashmaps
      • Options
      • Error Handling
      • Generics
      • Traits
      • Lifetimes
      • Tests
      • Iterators
      • Smart Pointers
      • Threads
      • Macros
      • Quiz 1
      • Quiz 2
      • Quiz 3
  • Software Engineering
    • CAP Theorem
    • Circuit Breaker
    • Decoupling
    • GraphQL: Query Caching
    • HMAC Signature
    • Idempotency
    • Monolith VS Microservice
    • OWASP Top 10 2021
    • PCI DSS
    • PostgreSQL: Partitioning
    • PostgreSQL: Replication
    • Protobuf & gRPC
    • Redis: Streams
    • Resource Scaling
    • Signed URL
    • SOLID
    • Stack VS Heap
    • Stateful VS Stateless
  • Site Reliability Engineering
    • Chaos Engineering
    • Distributed Tracing
    • Kubernetes (k8s)
    • SLA, SLO, and SLI Metrics
    • Site Reliability Engineer
  • Others
    • FFMPEG Cheat sheet
Powered by GitBook
On this page
  1. Golang

JSON: omitzero

In Go version 1.24 that will be release around February 2025 there is a feature that very useful in my opinion. That is new json tag option omitzero.

The "omitzero" option specifies that the field should be omitted from the encoding if the field has a zero value, according to rules:

  1. If the field type has an "IsZero() bool" method, that will be used to determine whether the value is zero.

  2. Otherwise, the value is zero if it is the zero value for its type.

From golang official docs, the field that have omitzero tags and has zero value by either IsZero() method or zero value for its type will be excluded.

Let's take an example:

func main() {
    type Address struct {
        City    string `json:"city"`
        Country string `json:"country"`
    }

    type Payload struct {
        Name        string    `json:"name,omitempty"`
        Age         int       `json:"age,omitempty"`
        DateOfBirth time.Time `json:"date_of_birth,omitempty"`
        Address     Address   `json:"address,omitempty"`
        Empty       struct{}  `json:"empty,omitempty"`
    }

    res, err := json.MarshalIndent(Payload{}, "", "    ")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(res))
}

Output:

{
    "date_of_birth": "0001-01-01T00:00:00Z",
    "address": {
        "city": "",
        "country": ""
    },
    "empty": {}
}

The problem with omitempty tag is it only excluded value that are empty eg: false, 0, a nil pointer, a nil interface value, and any array, slice, map, or string that has zero length. So if you have a struct field that has empty value it still included even though the field has omitempty tag, unless we define the field as pointer and make it nil.

Same case with time.Time where the zero value is "0001-01-01T00:00:00Z". With omitempty it still included even it's zero value.

The omitzero tag will solve this problem in Go 1.24. We can use golang playground with dev branch version to try this:

func main() {
    type Address struct {
        City    string `json:"city"`
        Country string `json:"country"`
    }

    type Payload struct {
        Name        string    `json:"name,omitzero"`
        Age         int       `json:"age,omitzero"`
        DateOfBirth time.Time `json:"date_of_birth,omitzero"`
        Address     Address   `json:"address,omitzero"`
        Empty       struct{}  `json:"empty,omitzero"`
    }

    res, err := json.MarshalIndent(Payload{}, "", "  ")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(res))
}

Output:

{}

References

PreviousGoroutine: Performance & TradeoffsNextRust

Last updated 4 months ago

Golang Playground:

https://go.dev/play/p/jzBYfFFY9Yp?v=gotip
https://tip.golang.org/doc/go1.24
https://pkg.go.dev/encoding/json@master#Marshal
https://go.dev/tour/basics/12