• Stars
    star
    10
  • Rank 1,747,813 (Top 36 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 4 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Go package to quickly query and manipulate interface data.

IJSON
PkgGoDev Build and Test Status Go report
Query Interface JSON and set or delete values easily

IJSON is a small but effective utility to deal with dynamic or unknown JSON structures in Go. It's a helpful wrapper for navigating hierarchies of map[string]interface{} OR []interface{}. It is the best solution for one time data access and manipulation.

Other libraries parse the whole json structure in their own format and again to interface if required, not suitable if you have interface{} as input and want the output in same format.

Note - This is not a json parser. It just plays with raw interface data.

Features

  • Very fast in accessing and manipulating top level values.
  • Avoids parsing whole JSON structure to intermediate format. Saves allocations.
  • Easy API to perform query, set or delete operations on raw interface data.
  • One line syntax to chain multiple operations together.

Known limitations

  • Not suitable if you want to perform multiple operations on same data.

Getting started

Installation

go get -u github.com/akshaybharambe14/ijson

Usage and Example

This package provides two types of functions. The functions suffixed with <action>P accept a path separated by ".".

Ex. "#0.friends.#~name"

package main

import (
	"fmt"

	"github.com/akshaybharambe14/ijson"
)

var dataBytes = []byte(`
[
	{
	  "index": 0,
	  "friends": [
		{
		  "id": 0,
		  "name": "Justine Bird"
		},
		{
		  "id": 0,
		  "name": "Justine Bird"
		},
		{
		  "id": 1,
		  "name": "Marianne Rutledge"
		}
	  ]
	}
]
`)

func main() {
	r := ijson.ParseByes(dataBytes).
		GetP("#0.friends.#~name"). // list the friend names for 0th record -
		// []interface {}{"Justine Bird", "Justine Bird", "Marianne Rutledge"}

		Del("#0"). // delete 0th record
		// []interface {}{"Marianne Rutledge", "Justine Bird"}

		Set("tom", "#") // append "tom" in the list
		// []interface {}{"Marianne Rutledge", "Justine Bird", "tom"}

	fmt.Printf("%#v\n", r.Value())

	// returns error if the data type differs than the type expected by query
	fmt.Println(r.Set(1, "name").Error())
}

Path syntax

IJSON follows a specific path syntax to access the data. The implementation sticks to the analogy that, user knows the path. So if caller wants to access an index, the underlying data must be an array otherwise, an error will be returned.

Use functions and methods suffixed by P to provide a "." separated path.

Get

{
	"index": 0,
	"name": { "first": "Tom", "last": "Anderson" },
	"friends": [
		{ "id": 1, "name": "Justine Bird" },
		{ "id": 2, "name": "Justine Rutledge" },
		{ "id": 3, "name": "Marianne Rutledge" }
	]
}

Summary of get operations on above data.

"name.last"    >> "Anderson"                          // GET "last" field from "name" object
"friends.#"    >> 3                                   // GET length of "friends" array
"friends.#~id" >> [ 1, 2, 3 ]                         // GET all values of "id" field from "friends" array
"friends.#0"   >> { "id": 1, "name": "Justine Bird" } // GET "0th" element from "friends" array

Set

Set overwrites the existing data. An error will be returned if the data does not match the query. If the data is nil, it will create the structure.

There is an alternative for datatype mismatch. Use SetF instead of Set function. It will forcefully replace the existing with provided.

Following path syntax sets "Anderson" as a value in empty structure.

"name.last"    >> { "name": { "last": "Anderson" } }  // Create an object and SET value of "last" field in "name" object
"#2"           >> ["", "", "Anderson"]                // Create an array and SET value at "2nd" index
"friends.#"    >> { "friends": [ "Anderson" ] }       // Create an object and APPEND to "friends" array

Delete

While deleting at an index, you have two options. By default, deletes does not preserve order. This helps to save unnecessary allocations as it just replaces the data at given index with last element. Refer following syntax for details.

{
	"index": 0,
	"friends": ["Justine Bird", "Justine Rutledge", "Marianne Rutledge"]
}

Summary of delete operations on above data.

"index"        >> { "friends": [ "Justine Bird", "Justine Rutledge", "Marianne Rutledge" ] } // DELETE "index" field
"friends.#"    >> { "index": 0, "friends": [ "Justine Bird", "Justine Rutledge" ] }          // DELETE last element from "friends" array
"friends.#0"   >> { "index": 0, "friends": [ "Marianne Rutledge", "Justine Rutledge" ] }     // DELETE "0th" element from "friends" array WITHOUT preserving order
"friends.#~0"  >> { "index": 0, "friends": [ "Justine Rutledge", "Marianne Rutledge" ] }     // DELETE "0th" element from "friends" array WITH preserving order

Operations chaining

You can chain multiple operations and check if it succeeds or fails.

    r := ijson.New(data).Get("#0", "friends", "#~name").Del("#0").Set(value, "#")
    if r.Error() != nil {
        ...
    }

    // access value
    _ = r.Value()

Parsing the json

This package uses standard library encoding/json as a json parser. We already have a very wide range of json parsers. I would recommend GJSON. It is probably the fastest, as far as I know.

See ijson.ParseBytes() and ijson.Parse() functions.

Please check following awesome projects, you might find a better match for you.

  1. GJSON, SJSON
  2. FASTJSON
  3. GABS

Contact

Akshay Bharambe @akshaybharambe1

License

IJSON source code is available under the MIT License.

More Repositories

1

gouf

Most commonly used utility/helper functions for generic types in Go.
Go
18
star
2

golang-examples

This repository contains sample golang examples which I come across while learning or trying new things. It also contains tests and benchmarks of various operations.
Go
11
star
3

docgo

Now you are just a click away from official package documentation for Go repositories. DOCGO is a handy browser extension 🧱 to redirect from Go source code repositories to their official documentation πŸ“„.
CSS
11
star
4

go-jsonc

go-jsonc provides a way to work with commented json by converting it to plain json.
Go
10
star
5

gowp

High performance, type safe, concurrency limiting worker pool package for golang!
Go
4
star
6

gofl

Generic Free List implementation to reuse memory and avoid allocations
Go
3
star
7

cloud-native-go

Introduction to docker and kubernetes with cloud native Go.
2
star
8

vue-js-template-project

A template project for vue js with configured eslint and prettier.
Vue
2
star
9

go-docker

Simple tutorial to containerize and publish your go app to Docker
Dockerfile
2
star
10

go-workerpool

A worker pool in go.
Go
2
star
11

golang-concurrent-csv

golang-concurrent-csv
1
star
12

spinner

Simple spinner for golang CLI apps.
Go
1
star
13

akshaybharambe14.github.io

Portfolio website
1
star
14

modulesExample

An example to get started with golang modules
Go
1
star
15

portfolioDev

Portfoio Website
1
star
16

akshaybharambe14

1
star
17

go-unusual

Some functionalities that are unusual/unsafe, but are useful in some edge/exceptional cases.
1
star
18

golang-postgresql-example

Go
1
star
19

gohooks

GoHooks make it easy to send and consume secured web-hooks from a Go application
Go
1
star
20

one-click-hugo-cms

CSS
1
star
21

go-generics-tests-bug

Details of a bug in compiling tests files with generic code.
Go
1
star
22

go-rotate

Go
1
star