Top Related Projects
Fast JSON parser and validator for Go. No custom structs, no code generation, no reflection
Get JSON values quickly - JSON parser for Go
One of the fastest alternative JSON parser for Go that does not require schema
a Go package to interact with arbitrary JSON
Fast JSON serializer for golang.
A high-performance 100% compatible drop-in replacement of "encoding/json"
Quick Overview
Gabs (Go Advanced Buffered Scanner) is a small utility library for parsing, creating, and editing unknown JSON in Go. It provides a simple API for dynamically navigating and manipulating JSON structures without the need for predefined structs, making it particularly useful for working with dynamic or unpredictable JSON data.
Pros
- Easy to use API for parsing and manipulating JSON
- Supports dynamic JSON navigation without predefined structs
- Efficient memory usage with buffered scanning
- Allows for creation and editing of JSON structures
Cons
- Limited to JSON data format only
- May be less performant than struct-based parsing for known JSON structures
- Lacks some advanced features found in larger JSON libraries
- Documentation could be more comprehensive
Code Examples
- Parsing JSON and accessing values:
jsonParsed, _ := gabs.ParseJSON([]byte(`{"name":{"first":"Tom","last":"Anderson"},"age":37}`))
firstName := jsonParsed.Path("name.first").Data().(string)
fmt.Println(firstName) // Output: Tom
- Creating and modifying JSON:
json := gabs.New()
json.Set(10, "numbers", "1")
json.Set(20, "numbers", "2")
json.Set(30, "numbers", "3")
fmt.Println(json.String()) // Output: {"numbers":{"1":10,"2":20,"3":30}}
- Working with arrays:
jsonParsed, _ := gabs.ParseJSON([]byte(`{"array":["a","b","c"]}`))
jsonParsed.ArrayAppend("d", "array")
fmt.Println(jsonParsed.Path("array").Index(3).Data().(string)) // Output: d
Getting Started
To use Gabs in your Go project, first install it:
go get github.com/Jeffail/gabs/v2
Then import it in your Go code:
import "github.com/Jeffail/gabs/v2"
Now you can start using Gabs to parse and manipulate JSON:
jsonObj, _ := gabs.ParseJSON([]byte(`{"name":"John","age":30}`))
name := jsonObj.Path("name").Data().(string)
fmt.Println(name) // Output: John
Competitor Comparisons
Fast JSON parser and validator for Go. No custom structs, no code generation, no reflection
Pros of fastjson
- Significantly faster JSON parsing and encoding
- Lower memory usage and fewer allocations
- Supports streaming JSON processing for large datasets
Cons of fastjson
- Less feature-rich API compared to gabs
- Requires more manual handling of JSON structures
- Limited support for modifying existing JSON objects
Code Comparison
gabs:
jsonObj, _ := gabs.ParseJSON([]byte(`{"name":"John","age":30}`))
name := jsonObj.Path("name").Data().(string)
jsonObj.Set(31, "age")
fastjson:
var p fastjson.Parser
v, _ := p.Parse(`{"name":"John","age":30}`)
name := string(v.GetStringBytes("name"))
v.Set("age", fastjson.MustParse("31"))
Both libraries provide JSON parsing and manipulation capabilities, but they differ in their approach and performance characteristics. gabs offers a more user-friendly API with convenient methods for accessing and modifying JSON data, while fastjson focuses on high-performance parsing and encoding at the cost of a slightly more complex API.
fastjson is particularly well-suited for applications that require fast processing of large JSON datasets or have strict performance requirements. On the other hand, gabs may be more appropriate for projects where ease of use and a rich feature set are prioritized over raw performance.
Get JSON values quickly - JSON parser for Go
Pros of gjson
- Faster performance for parsing and retrieving JSON data
- More extensive query syntax for complex JSON operations
- Supports modifying JSON data with Get-Set-Get pattern
Cons of gjson
- Limited JSON creation capabilities compared to gabs
- Less intuitive for building JSON structures from scratch
- Steeper learning curve for advanced query syntax
Code Comparison
gabs example:
jsonObj := gabs.New()
jsonObj.Set(10, "foo", "bar", "baz")
jsonObj.Set(20, "foo", "bar", "qux")
fmt.Println(jsonObj.String())
gjson example:
json := `{"foo":{"bar":{"baz":10,"qux":20}}}`
value := gjson.Get(json, "foo.bar.baz")
fmt.Println(value.Int())
Both libraries offer JSON parsing and manipulation capabilities, but they have different strengths. gabs excels in creating and modifying JSON structures, while gjson focuses on fast parsing and querying of existing JSON data. The choice between them depends on the specific requirements of your project, such as performance needs, JSON creation vs. parsing, and the complexity of operations you need to perform on JSON data.
One of the fastest alternative JSON parser for Go that does not require schema
Pros of jsonparser
- Faster performance, especially for large JSON files
- Lower memory usage due to not creating intermediate objects
- Supports streaming JSON parsing
Cons of jsonparser
- Less intuitive API for complex operations
- Limited support for modifying JSON structures
- Requires more manual handling of data types
Code Comparison
jsonparser:
data := []byte(`{"name": "John", "age": 30}`)
name, err := jsonparser.GetString(data, "name")
age, err := jsonparser.GetInt(data, "age")
gabs:
jsonParsed, err := gabs.ParseJSON([]byte(`{"name": "John", "age": 30}`))
name := jsonParsed.Path("name").Data().(string)
age := jsonParsed.Path("age").Data().(float64)
Summary
jsonparser is optimized for performance and memory efficiency, making it ideal for processing large JSON files or high-throughput applications. It excels in scenarios where speed and resource conservation are crucial.
gabs offers a more user-friendly API for complex JSON manipulations and modifications. It's better suited for applications that require frequent JSON structure alterations or when ease of use is prioritized over raw performance.
Choose jsonparser for high-performance, read-heavy operations on large JSON datasets. Opt for gabs when working with smaller JSON structures or when frequent modifications and a more intuitive API are needed.
a Go package to interact with arbitrary JSON
Pros of go-simplejson
- Simpler API with fewer methods, making it easier to learn and use
- More flexible for handling unknown JSON structures
- Better support for chaining operations
Cons of go-simplejson
- Less performant than gabs for large JSON documents
- Fewer advanced features and manipulation options
- Limited support for creating or modifying JSON structures
Code Comparison
go-simplejson:
js, _ := simplejson.NewJson([]byte(`{"name":"John","age":30}`))
name, _ := js.Get("name").String()
age, _ := js.Get("age").Int()
gabs:
jsonParsed, _ := gabs.ParseJSON([]byte(`{"name":"John","age":30}`))
name := jsonParsed.Path("name").Data().(string)
age := jsonParsed.Path("age").Data().(float64)
Both libraries provide ways to parse and access JSON data, but gabs offers more advanced features for manipulation and creation of JSON structures. go-simplejson is simpler to use and more flexible for handling unknown JSON structures, while gabs is more performant and feature-rich. The choice between them depends on the specific requirements of your project, such as performance needs, JSON manipulation complexity, and ease of use.
Fast JSON serializer for golang.
Pros of easyjson
- Generates code for faster JSON encoding/decoding, resulting in better performance
- Supports custom MarshalJSON/UnmarshalJSON methods for fine-grained control
- Integrates well with Go's standard encoding/json package
Cons of easyjson
- Requires code generation step, which adds complexity to the build process
- Less flexible for dynamic JSON manipulation compared to gabs
- Steeper learning curve for newcomers due to code generation approach
Code Comparison
easyjson:
//easyjson:json
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
gabs:
jsonParsed, _ := gabs.ParseJSON([]byte(`{"name":"John","age":30}`))
name := jsonParsed.Path("name").Data().(string)
age := jsonParsed.Path("age").Data().(float64)
Summary
easyjson focuses on performance through code generation, making it ideal for projects with known JSON structures and high-performance requirements. gabs, on the other hand, offers more flexibility for dynamic JSON manipulation without code generation. Choose easyjson for speed and static typing, or gabs for ease of use and dynamic JSON handling.
A high-performance 100% compatible drop-in replacement of "encoding/json"
Pros of json-iterator/go
- Significantly faster JSON parsing and serialization
- Drop-in replacement for the standard library's encoding/json
- Supports custom extensions and configurations
Cons of json-iterator/go
- Less intuitive for complex JSON manipulation
- Requires more setup for advanced use cases
Code Comparison
json-iterator/go:
import jsoniter "github.com/json-iterator/go"
var json = jsoniter.ConfigCompatibleWithStandardLibrary
data := json.Get(input, "users", 0, "name").ToString()
gabs:
import "github.com/Jeffail/gabs/v2"
jsonParsed, _ := gabs.ParseJSON([]byte(input))
data, _ := jsonParsed.Path("users.0.name").Data().(string)
Key Differences
- json-iterator/go focuses on performance and compatibility with the standard library
- gabs provides a more intuitive API for JSON manipulation and querying
- json-iterator/go is better suited for high-performance applications
- gabs is more convenient for complex JSON operations and data extraction
Use Cases
- Choose json-iterator/go for applications requiring high-speed JSON processing
- Opt for gabs when working with complex JSON structures and frequent data manipulation
Both libraries have their strengths, and the choice depends on specific project requirements and performance needs.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Gabs is a small utility for dealing with dynamic or unknown JSON structures in Go. It's pretty much just a helpful wrapper for navigating hierarchies of map[string]interface{}
objects provided by the encoding/json
package. It does nothing spectacular apart from being fabulous.
If you're migrating from version 1 check out migration.md
for guidance.
Use
Import
Using modules:
import (
"github.com/Jeffail/gabs/v2"
)
Without modules:
import (
"github.com/Jeffail/gabs"
)
Parsing and searching JSON
jsonParsed, err := gabs.ParseJSON([]byte(`{
"outer":{
"inner":{
"value1":10,
"value2":22
},
"alsoInner":{
"value1":20,
"array1":[
30, 40
]
}
}
}`))
if err != nil {
panic(err)
}
var value float64
var ok bool
value, ok = jsonParsed.Path("outer.inner.value1").Data().(float64)
// value == 10.0, ok == true
value, ok = jsonParsed.Search("outer", "inner", "value1").Data().(float64)
// value == 10.0, ok == true
value, ok = jsonParsed.Search("outer", "alsoInner", "array1", "1").Data().(float64)
// value == 40.0, ok == true
gObj, err := jsonParsed.JSONPointer("/outer/alsoInner/array1/1")
if err != nil {
panic(err)
}
value, ok = gObj.Data().(float64)
// value == 40.0, ok == true
value, ok = jsonParsed.Path("does.not.exist").Data().(float64)
// value == 0.0, ok == false
exists := jsonParsed.Exists("outer", "inner", "value1")
// exists == true
exists = jsonParsed.ExistsP("does.not.exist")
// exists == false
Iterating objects
jsonParsed, err := gabs.ParseJSON([]byte(`{"object":{"first":1,"second":2,"third":3}}`))
if err != nil {
panic(err)
}
// S is shorthand for Search
for key, child := range jsonParsed.S("object").ChildrenMap() {
fmt.Printf("key: %v, value: %v\n", key, child.Data().(float64))
}
Iterating arrays
jsonParsed, err := gabs.ParseJSON([]byte(`{"array":["first","second","third"]}`))
if err != nil {
panic(err)
}
for _, child := range jsonParsed.S("array").Children() {
fmt.Println(child.Data().(string))
}
Will print:
first
second
third
Children() will return all children of an array in order. This also works on objects, however, the children will be returned in a random order.
Searching through arrays
If your structure contains arrays you must target an index in your search.
jsonParsed, err := gabs.ParseJSON([]byte(`{"array":[{"value":1},{"value":2},{"value":3}]}`))
if err != nil {
panic(err)
}
fmt.Println(jsonParsed.Path("array.1.value").String())
Will print 2
.
Generating JSON
jsonObj := gabs.New()
// or gabs.Wrap(jsonObject) to work on an existing map[string]interface{}
jsonObj.Set(10, "outer", "inner", "value")
jsonObj.SetP(20, "outer.inner.value2")
jsonObj.Set(30, "outer", "inner2", "value3")
fmt.Println(jsonObj.String())
Will print:
{"outer":{"inner":{"value":10,"value2":20},"inner2":{"value3":30}}}
To pretty-print:
fmt.Println(jsonObj.StringIndent("", " "))
Will print:
{
"outer": {
"inner": {
"value": 10,
"value2": 20
},
"inner2": {
"value3": 30
}
}
}
Generating Arrays
jsonObj := gabs.New()
jsonObj.Array("foo", "array")
// Or .ArrayP("foo.array")
jsonObj.ArrayAppend(10, "foo", "array")
jsonObj.ArrayAppend(20, "foo", "array")
jsonObj.ArrayAppend(30, "foo", "array")
fmt.Println(jsonObj.String())
Will print:
{"foo":{"array":[10,20,30]}}
Working with arrays by index:
jsonObj := gabs.New()
// Create an array with the length of 3
jsonObj.ArrayOfSize(3, "foo")
jsonObj.S("foo").SetIndex("test1", 0)
jsonObj.S("foo").SetIndex("test2", 1)
// Create an embedded array with the length of 3
jsonObj.S("foo").ArrayOfSizeI(3, 2)
jsonObj.S("foo").Index(2).SetIndex(1, 0)
jsonObj.S("foo").Index(2).SetIndex(2, 1)
jsonObj.S("foo").Index(2).SetIndex(3, 2)
fmt.Println(jsonObj.String())
Will print:
{"foo":["test1","test2",[1,2,3]]}
Converting back to JSON
This is the easiest part:
jsonParsedObj, _ := gabs.ParseJSON([]byte(`{
"outer":{
"values":{
"first":10,
"second":11
}
},
"outer2":"hello world"
}`))
jsonOutput := jsonParsedObj.String()
// Becomes `{"outer":{"values":{"first":10,"second":11}},"outer2":"hello world"}`
And to serialize a specific segment is as simple as:
jsonParsedObj := gabs.ParseJSON([]byte(`{
"outer":{
"values":{
"first":10,
"second":11
}
},
"outer2":"hello world"
}`))
jsonOutput := jsonParsedObj.Search("outer").String()
// Becomes `{"values":{"first":10,"second":11}}`
Merge two containers
You can merge a JSON structure into an existing one, where collisions will be converted into a JSON array.
jsonParsed1, _ := ParseJSON([]byte(`{"outer":{"value1":"one"}}`))
jsonParsed2, _ := ParseJSON([]byte(`{"outer":{"inner":{"value3":"three"}},"outer2":{"value2":"two"}}`))
jsonParsed1.Merge(jsonParsed2)
// Becomes `{"outer":{"inner":{"value3":"three"},"value1":"one"},"outer2":{"value2":"two"}}`
Arrays are merged:
jsonParsed1, _ := ParseJSON([]byte(`{"array":["one"]}`))
jsonParsed2, _ := ParseJSON([]byte(`{"array":["two"]}`))
jsonParsed1.Merge(jsonParsed2)
// Becomes `{"array":["one", "two"]}`
Parsing Numbers
Gabs uses the json
package under the bonnet, which by default will parse all number values into float64
. If you need to parse Int
values then you should use a json.Decoder
:
sample := []byte(`{"test":{"int":10,"float":6.66}}`)
dec := json.NewDecoder(bytes.NewReader(sample))
dec.UseNumber()
val, err := gabs.ParseJSONDecoder(dec)
if err != nil {
t.Errorf("Failed to parse: %v", err)
return
}
intValue, err := val.Path("test.int").Data().(json.Number).Int64()
Top Related Projects
Fast JSON parser and validator for Go. No custom structs, no code generation, no reflection
Get JSON values quickly - JSON parser for Go
One of the fastest alternative JSON parser for Go that does not require schema
a Go package to interact with arbitrary JSON
Fast JSON serializer for golang.
A high-performance 100% compatible drop-in replacement of "encoding/json"
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot