jsonata

package module
v1.5.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 11, 2021 License: MIT Imports: 15 Imported by: 13

README

JSONata in Go

Package jsonata is a query and transformation language for JSON. It's a Go port of the JavaScript library JSONata.

It currently has feature parity with jsonata-js 1.5.4. As well as a most of the functions added in newer versions. You can see potentially missing functions by looking at the jsonata-js changelog.

Install

go get github.com/blues/jsonata-go

Usage

import (
	"encoding/json"
	"fmt"
	"log"

	jsonata "github.com/blues/jsonata-go"
)

const jsonString = `
    {
        "orders": [
            {"price": 10, "quantity": 3},
            {"price": 0.5, "quantity": 10},
            {"price": 100, "quantity": 1}
        ]
    }
`

func main() {

	var data interface{}

	// Decode JSON.
	err := json.Unmarshal([]byte(jsonString), &data)
	if err != nil {
		log.Fatal(err)
	}

	// Create expression.
	e := jsonata.MustCompile("$sum(orders.(price*quantity))")

	// Evaluate.
	res, err := e.Eval(data)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(res)
	// Output: 135
}

JSONata Server

A locally hosted version of JSONata Exerciser for testing is available here.

JSONata tests

A CLI tool for running jsonata-go against the JSONata test suite is available here.

Contributing

We love issues, fixes, and pull requests from everyone. Please run the unit-tests, staticcheck, and goimports prior to submitting your PR. By participating in this project, you agree to abide by the Blues Inc code of conduct.

For details on contributions we accept and the process for contributing, see our contribution guide.

In addition to the Go unit tests there is also a test runner that will run against the jsonata-js test suite in the jsonata-test directory. A number of these tests currently fail, but we're working towards feature parity with the jsonata-js reference implementation. Pull requests welcome!

If you would like to contribute to this library a good first issue would be to run the jsonata-test suite, and fix any of the tests not passing.

Documentation

Overview

Package jsonata is a query and transformation language for JSON. It's a Go port of the JavaScript library JSONata. Please use the official JSONata site as a language reference.

http://jsonata.org/

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrUndefined = errors.New("no results found")

ErrUndefined is returned by the evaluation methods when a JSONata expression yields no results. Unlike most errors, ErrUndefined does not mean that evaluation failed.

The simplest way to trigger ErrUndefined is to look up a field that is not present in the JSON data. Many JSONata operators and functions also return ErrUndefined when called with undefined inputs.

Functions

func RegisterExts

func RegisterExts(exts map[string]Extension) error

RegisterExts registers custom functions for use in JSONata expressions. It is designed to be called once on program startup (e.g. from an init function).

Custom functions registered at the package level will be available to all Expr objects. To register custom functions with specific Expr objects, use the RegisterExts method.

func RegisterVars

func RegisterVars(vars map[string]interface{}) error

RegisterVars registers custom variables for use in JSONata expressions. It is designed to be called once on program startup (e.g. from an init function).

Custom variables registered at the package level will be available to all Expr objects. To register custom variables with specific Expr objects, use the RegisterVars method.

Types

type ArgCountError

type ArgCountError struct {
	Func     string
	Expected int
	Received int
}

ArgCountError is returned by the evaluation methods when an expression contains a function call with the wrong number of arguments.

func (ArgCountError) Error

func (e ArgCountError) Error() string

type ArgTypeError

type ArgTypeError struct {
	Func  string
	Which int
}

ArgTypeError is returned by the evaluation methods when an expression contains a function call with the wrong argument type.

func (ArgTypeError) Error

func (e ArgTypeError) Error() string

type ErrType

type ErrType uint

ErrType indicates the reason for an error.

const (
	ErrNonIntegerLHS ErrType = iota
	ErrNonIntegerRHS
	ErrNonNumberLHS
	ErrNonNumberRHS
	ErrNonComparableLHS
	ErrNonComparableRHS
	ErrTypeMismatch
	ErrNonCallable
	ErrNonCallableApply
	ErrNonCallablePartial
	ErrNumberInf
	ErrNumberNaN
	ErrMaxRangeItems
	ErrIllegalKey
	ErrDuplicateKey
	ErrClone
	ErrIllegalUpdate
	ErrIllegalDelete
	ErrNonSortable
	ErrSortMismatch
)

Types of errors that may be encountered by JSONata.

type EvalError

type EvalError struct {
	Type  ErrType
	Token string
	Value string
}

An EvalError represents an error during evaluation of a JSONata expression.

func (EvalError) Error

func (e EvalError) Error() string

type Expr

type Expr struct {
	// contains filtered or unexported fields
}

An Expr represents a JSONata expression.

func Compile

func Compile(expr string) (*Expr, error)

Compile parses a JSONata expression and returns an Expr that can be evaluated against JSON data. If the input is not a valid JSONata expression, Compile returns an error of type jparse.Error.

func MustCompile

func MustCompile(expr string) *Expr

MustCompile is like Compile except it panics if given an invalid expression.

func (*Expr) Eval

func (e *Expr) Eval(data interface{}) (interface{}, error)

Eval executes a JSONata expression against the given data source. The input is typically the result of unmarshaling a JSON string. The output is an object suitable for marshaling into a JSON string. Use EvalBytes to skip the unmarshal/marshal steps and work solely with JSON strings.

Eval can be called multiple times, with different input data if required.

Example
package main

import (
	"encoding/json"
	"fmt"
	"log"

	jsonata "github.com/blues/jsonata-go"
)

const jsonString = `
    {
        "orders": [
            {"price": 10, "quantity": 3},
            {"price": 0.5, "quantity": 10},
            {"price": 100, "quantity": 1}
        ]
    }
`

func main() {

	var data interface{}

	// Decode JSON.
	err := json.Unmarshal([]byte(jsonString), &data)
	if err != nil {
		log.Fatal(err)
	}

	// Create expression.
	e := jsonata.MustCompile("$sum(orders.(price*quantity))")

	// Evaluate.
	res, err := e.Eval(data)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(res)
}
Output:

135

func (*Expr) EvalBytes

func (e *Expr) EvalBytes(data []byte) ([]byte, error)

EvalBytes is like Eval but it accepts and returns byte slices instead of objects.

func (*Expr) RegisterExts

func (e *Expr) RegisterExts(exts map[string]Extension) error

RegisterExts registers custom functions for use during evaluation. Custom functions registered with this method are only available to this Expr object. To make custom functions available to all Expr objects, use the package level RegisterExts function.

Example
package main

import (
	"fmt"
	"log"
	"strings"

	jsonata "github.com/blues/jsonata-go"
)

//
// This example demonstrates how to extend JSONata with
// custom functions.
//

// exts defines a function named "titlecase" which maps to
// the standard library function strings.Title. Any function,
// from the standard library or otherwise, can be used to
// extend JSONata, as long as it returns either one or two
// arguments (the second argument must be an error).
var exts = map[string]jsonata.Extension{
	"titlecase": {
		Func: strings.Title,
	},
}

func main() {

	// Create an expression that uses the titlecase function.
	e := jsonata.MustCompile(`$titlecase("beneath the underdog")`)

	// Register the titlecase function.
	err := e.RegisterExts(exts)
	if err != nil {
		log.Fatal(err)
	}

	// Evaluate.
	res, err := e.Eval(nil)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(res)
}
Output:

Beneath The Underdog

func (*Expr) RegisterVars

func (e *Expr) RegisterVars(vars map[string]interface{}) error

RegisterVars registers custom variables for use during evaluation. Custom variables registered with this method are only available to this Expr object. To make custom variables available to all Expr objects, use the package level RegisterVars function.

func (*Expr) String

func (e *Expr) String() string

String returns a string representation of an Expr.

type Extension

type Extension struct {

	// Func is a Go function that implements the custom
	// functionality and returns either one or two values.
	// The second return value, if provided, must be an
	// error.
	Func interface{}

	// UndefinedHandler is a function that determines how
	// this extension handles undefined arguments. If
	// UndefinedHandler is non-nil, it is called before
	// Func with the same arguments. If the handler returns
	// true, Func is not called and undefined is returned
	// instead.
	UndefinedHandler jtypes.ArgHandler

	// EvalContextHandler is a function that determines how
	// this extension handles missing arguments. If
	// EvalContextHandler is non-nil, it is called before
	// Func with the same arguments. If the handler returns
	// true, the evaluation context is inserted as the first
	// argument when Func is called.
	EvalContextHandler jtypes.ArgHandler
}

An Extension describes custom functionality added to a JSONata expression.

Directories

Path Synopsis
Package jlib implements the JSONata function library.
Package jlib implements the JSONata function library.
Package jparse converts JSONata expressions to abstract syntax trees.
Package jparse converts JSONata expressions to abstract syntax trees.
Package jtypes (golint) Package jtypes provides types and utilities for third party extension functions.
Package jtypes (golint) Package jtypes provides types and utilities for third party extension functions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL