WARNING: This server provides a static reference view of the NetKernel documentation. Links to dynamic content do not work. For the best experience we recommend you install NetKernel and view the documentation in the live system .

Endpoint
Name:active:jsonrl
Description:JSON Recursion Language runtime
Id:active:jsonrl
Category:accessor
Identifier Syntax

active:jsonrl is an accessor using Active URI syntax with the following base identifiers:

Base
active:jsonrl

and the following arguments: (for more details on argument passing details see here)

ArgumentRulesTypingDescription
operator
Mandatory
Representation (java.lang.Object)The JSON template to start recursing
tolerant
Optional
Representation (java.lang.Object)If present indicates that errors should be tolerated
varargs [varargs] Any quantityRepresentation (java.lang.Object)Varargs allows an arbitrary number of additional unspecified arguments.
Request Verbs

The following verb is supported:

Verb
SOURCE
Response

The following response representations can be returned for SOURCE requests:

SOURCE Representations
JSONObject

This accessor throws no documented exceptions.

Import Requirements

To use active:jsonrl accessor you must import the module urn:org:netkernel:json:extra:

<import>
  <uri>urn:org:netkernel:json:extra</uri>
</import>

active:jsonrl is a recursive composition language for JSON. It belongs to the family of recursive composition runtimes that includes XRL, HRL and TRL.

The general principle of the *RL family is that declarative resource requests embedded in a representation provide links which are recursively evaluated and the resulting representation is substituted into the primary resource structure (much like an HTML page provides linked references that are requested and composited into the final Web page).

The power of the *RL family is that the requests support the full ROC request model - meaning that embedded requests can implement both pull and push state transfer patterns.

JSONRL Requests

JSON is fundamentally a map datastructure - which, unlike XML, imposes certain constraints on request declaration and the resulting substitution - for example, no two entries can share the same name (key) in a JSON document.

To deal with this limitation, declarative requests must be marked with the following reserved prefix request- ("request" followed by a "dash").

Here is an example...

Say we have two JSON resources...

res:/car.json

[
            {"id": 10, "color": "silver", "name": "Volvo"},
            {"id": 11, "color": "red",    "name": "Saab"},
            {"id": 12, "color": "red",    "name": "Peugeot"},
            {"id": 13, "color": "yellow", "name": "Porsche"}
]

and res:/bike.json

[
            {"id": 20, "color": "black", "name": "Cannondale"},
            {"id": 21, "color": "red",   "name": "Shimano"}
]

If we have a JSONRL structure called res:/vehicles.json that has the following embedded JSONRL requests....

{
	"request-car" : "res:/car.json",
	"request-bike" : "res:/bike.json"
}

If we request the evaluation of the vehicles.json JSONRL template...

req=context.createRequest("active:jsonrl")
req.addArgument("operator","res:/vehicles.json")
rep=context.issueRequest(req)

then the resulting composite representation is...

{
        "car": [
            {"id": 10, "color": "silver", "name": "Volvo"},
            {"id": 11, "color": "red",    "name": "Saab"},
            {"id": 12, "color": "red",    "name": "Peugeot"},
            {"id": 13, "color": "yellow", "name": "Porsche"}
        ],
        "bike": [
            {"id": 20, "color": "black", "name": "Cannondale"},
            {"id": 21, "color": "red",   "name": "Shimano"}
        ]
}

Notice that "request-car" has been replaced and the JSON map now has the entry "car" (the "request-" prefix is removed and the name following the prefix becomes the JSON map key).

Maps and Arrays

JSONRL supports JSONObject (map) and JSONArray structures both for the included composite, the primary template and for the location of "request-XXX" references.

Clearly it is imperative that any requested resource is JSON (or is transreptable to JSONObject or JSONArray).

Basic Request Syntax

If the value associated with a "request-xxx" map entry is a string, then the string is treated as a declarative request. Since JSON does not support multi-line strings the string is treated as abbreviated declarative request syntax.

For example the following request shows the full capability of the requests...

{
	"request-GroovyExample" : "active:groovy operator res:/somescript.gy operand res:/foo"
}

Advanced Request Syntax

If the value associated with a "request-xxx" map entry is a map, then the "identifier" entry is taken as the abbreviated declarative request and the additional options "async" and "terminate" are also supported.

For example, this issues the same request as the example above, but this time it is performed asynchronously...

{
	"request-GroovyExample" : {
		"identifier" : "active:groovy operator res:/somescript.gy operand res:/foo",
		"async": true
		}
}

The power of asynchronous evaluation can be seen when dealing with high-latency requests. For example, the following JSONRL performs a mashup (composition) of three different JSON test microservices...

{
	"request-Time" : { "identifier" : "http://date.jsontest.com/", "async" : true },
	"request-Headers" : { "identifier" : "http://headers.jsontest.com/", "async" : true },
	"request-EchoJSON" : { "identifier" : "http://echo.jsontest.com/key/value/one/two", "async" : true }
}

The remote jsontest.com endpoints are not very fast so if done sequentially this takes about 800ms, however if done asynchronously in parallel (with "async" : true) it takes about 200ms.

Recursion

As with all *RL languages, JSONRL is recursive. That is, by default the requested JSON will also be evaluated and any "request-XXX" entries that it may also contain will themselves be evaluated. Recursion continues until all request references have been discovered.

Sometimes it can be important (eg for security when compositing external JSON resources), to force the explicit termination of recursion for a given request. Termination requires that you use the Advanced request syntax (above) and specify the "terminate": true map entry.

For example here is the three way mashup again but this time each included remote microservice result is not recursed...

{
	"request-Time" : { "identifier" : "http://date.jsontest.com/", "async" : true, "terminate": true },
	"request-Headers" : { "identifier" : "http://headers.jsontest.com/", "async" : true, "terminate": true },
	"request-EchoJSON" : { "identifier" : "http://echo.jsontest.com/key/value/one/two", "async" : true, "terminate": true }
}