Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.
/ jsonfilter Public archive

🔎 Filters the JSON data with `a/b/c` syntax

License

Notifications You must be signed in to change notification settings

teacat/jsonfilter

Repository files navigation

JSON Filter 台灣正體 GoDoc Coverage Status Build Status Go Report Card

JSON Filter is a GraphQL-like but for REST API or common usage to filter the JSON data. With JSON Filter, you are able to filter the JSON with users(username,nickname) like syntax.

Features

  • Filter the JSON data.
  • Easy to use.

Why?

GraphQL solves the problem but it takes time to design a perfect schema/system. While REST is the most quickly and easily to implement, we might still wanted to get the same benifit as GraphQL as possible.

The REST API has it's own problems, like: Over-fetching, Under-fetching. You might get too many unnecessary data, or you might get too few data.

Google solves the problem with thier own APIs by providing Partial Resources usage which you can filter the response with a fields=kind,items(title,characteristics/length) param.

Adobe does almost the same thing with a bit different syntax: ?fields=items[name,qty,sku].

Note

The current implementation is based on nemtsov/json-mask with JavaScript interpreter (powered by robertkrimen/otto) so the performance might needs to be considered.

The full-Golang solution is WIP and won't be implmeneted recently.

Installation

Install the package via go get command.

$ go get github.com/teacat/jsonfilter

Usage

A complete example:

package main

import (
	"fmt"
	"github.com/teacat/jsonfilter"
)

type User struct {
	ID       int      `json:"id"`
	Username string   `json:"username"`
	Email    string   `json:"email"`
	Phones   []string `json:"phones"`
}

func main() {
	data := []byte(`
{
    "id"      : 1,
    "username": "YamiOdymel",
    "email"   : "[email protected]",
    "phones"  : ["0912345678", "0987654321"]
}`)

	b, err := jsonfilter.Filter(data, "username,phones")
	if err != nil {
		panic(err)
	}

	var data MyData
	if err := json.Unmarshal(b, &data); err != nil {
		panic(err)
	}

	fmt.Printf("%+v", data) // Output: {ID:0 Username:YamiOdymel Email: Phones:[0912345678 0987654321]}
}

Syntax

The syntax is loosely based on XPath:

  • a,b,c Comma-separated list will select multiple fields.
  • a/b/c Path will select a field from its parent.
  • a(b,c) Sub-selection will select many fields from a parent.
  • a/*/c The star * wildcard will select all items in a field.

While trying to select the properties from the same parent,

use a(b,c) syntax instead of a/b,a/c because the a/c will override the results of a/b since the result won't be collected.

Also with wildcard syntax, you might get undesired results and this is an unknown issue from nemtsov / json-mask: * returns extra falsey values at the level of the wildcard #11.

Examples

The following JSON structure as the data source.

{
    "id": 1,
    "username": "YamiOdymel",
    "friends": [
        {
            "id": 2,
            "username": "Yan-K"
        }
    ],
    "information": {
        "address": "R.O.C (Taiwan)",
        "skills": [
            {
                "id": 1,
                "type": "eat"
            },
            {
                "id": 2,
                "type": "drink"
            }
        ]
    }
}

"id,username"

{
    "id": 1,
    "username": "YamiOdymel"
}

"friends(id,username)"

{
    "friends": [
        {
            "id": 2,
            "username": "Yan-K"
        }
    ]
}

"information/skills(type)"
"information/skills/type"
"information/*/type"

{
    "information": {
        "skills": [
            {
                "type": "eat"
            },
            {
                "type": "drink"
            }
        ]
    }
}