> For the complete documentation index, see [llms.txt](https://bagus-cahyono.gitbook.io/programming-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bagus-cahyono.gitbook.io/programming-notes/golang/json_omitzero.md).

# 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:

```go
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:

```json
{
    "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:

```go
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:

```json
{}
```

Golang Playground: <https://go.dev/play/p/jzBYfFFY9Yp?v=gotip>

## References

* <https://tip.golang.org/doc/go1.24>
* <https://pkg.go.dev/encoding/json@master#Marshal>
* <https://go.dev/tour/basics/12>
