Using JSON-e

An application of JSON-e typically allows the user to specify the template, and defines the context with which that template will be rendered as well as how the output will be interpreted. For example, an application that allows customized responses to chat messages might provide context {"message": .., "sender": ..} and expect an object of the form {"reply": ..} as a result.

JSON-e is intended for cross-platform usage, and has native implementations in several languages.

JavaScript

The JS module is installed into a Node project with

npm install --save json-e
yarn add json-e

The module exposes following interface:

import jsone from 'json-e';

var template = {a: {$eval: "foo.bar"}};
var context = {foo: {bar: "zoo"}};
console.log(jsone(template, context));
// -> { a: 'zoo' }

Note that the context can contain functions, and those functions can be called from the template:

var template = {$eval: "foo(1)"};
var context = {"foo": function(x) { return x + 2; }};
console.log(jsone(template, context));  // -> 3

NOTE: Context functions are called synchronously. Any complex asynchronous operations should be handled before rendering the template.

NOTE: If the template is untrusted, it can pass arbitrary data to functions in the context, which must guard against such behavior.

Browser

JSON-e has a single-file, browser-compatible implementation in dist/index.js in the NPM release. This file can be used directly in a browser to add JSON-e functionality.

JSON-e can be used from a CDN with

<script
  type="text/javascript"
  src="https://cdn.jsdelivr.net/npm/json-e">
</script>

TypeScript

The JS module is installed with either of

npm install --save json-e
yarn add json-e

Note: Type definitions are included with this package, so there's no need of seperate @types/.. installation.

As 'json-e' is a CommonJS module, the package must be imported like this (more..) for type definitions to work properly:

const jsone = require('json-e');

var template = {a: {$eval: "foo.bar"}};
var context = {foo: {bar: "zoo"}};
console.log(jsone(template, context));
// -> { a: 'zoo' }

Python

The Python distribution is installed with

pip install json-e

The distribution exposes a render function:

import jsone

template = {"a": {"$eval": "foo.bar"}}
context = {"foo": {"bar": "zoo"}}
print(jsone.render(template, context))  # -> {"a": "zoo"}

and also allows custom functions in the context:

template = {"$eval": "foo(1)"}
context = {"foo": lambda x: x + 2}
print(jsone.render(template, context))  # -> 3

Go (golang)

The golang package for json-e exposes a Render function:

import (
  "fmt"
  jsone "github.com/json-e/json-e/v4"
)

// Template must be given using types:
//   map[string]interface{}, []interface{}, float64, string, bool, nil
// The same types that json.Unmarshal() will create when targeting an interface{}
var template = map[string]interface{}{
  "result": map[string]interface{}{
    "$eval": "f() + 5",
  },
}
// Context can be JSON types just like template, but may also contain functions
// these can JSON types as arguments, and return a value and optionally an error.
var context = map[string]interface{}{
  "f": jsone.WrapFunction(func() float64 { return 37 }),
}

func main() {
  value, _ := jsone.Render(template, context)
  fmt.Printf("%#v\n", value)
}

Rust

The Rust crate exposes a render function which takes the template and context as serde_json Value objects, and returns an object of the same type.

use serde_json::json;

fn main() {
    println!("result: {:?}", json_e::render(
        json!({$eval: "a + b"}),
        json!({a: 10, b: 20})));
}

See docs.rs for the full API docs.

.NET

See json-everything for a .NET implementation of JSON-e.

Third-Party Integrations

rjsone

You can use the 3rd party package rjsone to template JSON-e from the command line, passing templates/contexts as files or arguments and using stdout for the result.

Bazel

You can use 3rd party Bazel rule to invoke rjsone (see above) from Bazel build files.

Terraform

The jsone Terraform provider allows use of JSON-e for templating objects within Terraform.