Skip to content

GJSON

Serialization & FormatsData/JSONGo

What it is

GJSON reads values from JSON with a dot-notation path syntax, without defining structs or unmarshalling the whole document.

Query with paths such as `books.0.title` or `books.#(year>1990)#.title`. GJSON scans rather than parsing the whole document, so it is fast for selective reads.

Installation

go get -u github.com/tidwall/gjson

Getting started

The smallest useful thing you can do with it, and what each part means.

Path queries
const data = `{"books":[
  {"title":"Dune","year":1965,"tags":["scifi"]},
  {"title":"Neuromancer","year":1984}
]}`

gjson.Get(data, "books.0.title").String()      // Dune
gjson.Get(data, "books.#").Int()               // 2 (count)
gjson.Get(data, "books.#.title").Array()       // [Dune Neuromancer]

// Filter, then project.
gjson.Get(data, `books.#(year>1970)#.title`)   // [Neuromancer]

if r := gjson.Get(data, "books.0.missing"); !r.Exists() {
    // Exists() distinguishes absent from a legitimate zero value.
}
Result.Exists() is important — String() on a missing path returns "", which is indistinguishable from a field that really is an empty string.

Advanced usage

Where the library earns its place over a simpler alternative.

Validate first, then iterate
if !gjson.Valid(payload) {
    return errors.New("invalid json")  // Get on invalid JSON has undefined results
}

gjson.Get(payload, "books").ForEach(func(_, value gjson.Result) bool {
    title := value.Get("title").String()
    year := value.Get("year").Int()
    process(title, year)
    return true // return false to stop early
})
GJSON does not validate as it scans, so calling Valid on untrusted input first is essential. ForEach avoids materialising the whole array.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

Empty results from a valid-looking path
Check Exists(). Array indices are zero-based and `#` is the count operator, not an index.
Nonsense values from malformed JSON
GJSON assumes well-formed input for speed. Guard with gjson.Valid.

Best practices

  • Call gjson.Valid on untrusted input before querying it.
  • Use Result.Exists() rather than comparing against the zero value.
  • Prefer encoding/json with a struct when you need the whole document — GJSON wins on selective reads.
  • Pair with sjson when you also need to set values without a full round trip.

Background

Why it exists, and what it was reacting to.

Written by Josh Baker, GJSON targets the case where you need three fields out of a large JSON payload and defining a matching struct would be pure overhead.