Camel Components

JSONata

Since Camel 3.5

Only producer is supported

The Jsonata component allows you to process JSON messages using the JSONATA specification. This can be ideal when doing JSON to JSON transformation and other transformations from JSON.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-jsonata</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>

URI format

jsonata:specName[?options]

Where specName is the classpath-local URI of the specification to invoke; or the complete URL of the remote specification (e.g.: file://folder/myfile.vm).

Configuring Options

Camel components are configured on two separate levels:

  • component level

  • endpoint level

Configuring Component Options

At the component level, you set general and shared configurations that are, then, inherited by the endpoints. It is the highest configuration level.

For example, a component may have security settings, credentials for authentication, urls for network connection and so forth.

Some components only have a few options, and others may have many. Because components typically have pre-configured defaults that are commonly used, then you may often only need to configure a few options on a component; or none at all.

You can configure components using:

  • the Component DSL.

  • in a configuration file (application.properties, *.yaml files, etc).

  • directly in the Java code.

Configuring Endpoint Options

You usually spend more time setting up endpoints because they have many options. These options help you customize what you want the endpoint to do. The options are also categorized into whether the endpoint is used as a consumer (from), as a producer (to), or both.

Configuring endpoints is most often done directly in the endpoint URI as path and query parameters. You can also use the Endpoint DSL and DataFormat DSL as a type safe way of configuring endpoints and data formats in Java.

A good practice when configuring options is to use Property Placeholders.

Property placeholders provide a few benefits:

  • They help prevent using hardcoded urls, port numbers, sensitive information, and other settings.

  • They allow externalizing the configuration from the code.

  • They help the code to become more flexible and reusable.

The following two sections list all the options, firstly for the component followed by the endpoint.

Component Options

The JSONata component supports the following options which are listed below.

Name Description Default Type

allowTemplateFromHeader (producer)

Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vulnerability if the header is coming from a malicious user, so use this with care.

false

boolean

contentCache (producer)

Sets whether to use resource content cache or not.

true

boolean

lazyStartProducer (producer)

Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel’s routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing.

false

boolean

autowiredEnabled (advanced)

Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which then gets configured on the component. This can be used for automatic configuring JDBC data sources, JMS connection factories, AWS Clients, etc.

true

boolean

frameBinding (advanced)

To configure custom frame bindings and inject user functions.

JsonataFrameBinding

Endpoint Options

The JSONata endpoint is configured using URI syntax:

jsonata:resourceUri

With the following path and query parameters:

Path Parameters

Name Description Default Type

resourceUri (producer)

Required Path to the resource. You can prefix with: classpath, file, http, ref, or bean. classpath, file and http loads the resource using these protocols (classpath is default). ref will lookup the resource in the registry. bean will call a method on a bean to be used as the resource. For bean you can specify the method name after dot, eg bean:myBean.myMethod.

String

Query Parameters

Name Description Default Type

allowContextMapAll (producer)

Sets whether the context map should allow access to all details. By default only the message body and headers can be accessed. This option can be enabled for full access to the current Exchange and CamelContext. Doing so impose a potential security risk as this opens access to the full power of CamelContext API.

false

boolean

allowTemplateFromHeader (producer)

Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vulnerability if the header is coming from a malicious user, so use this with care.

false

boolean

contentCache (producer)

Sets whether to use resource content cache or not.

true

boolean

inputType (producer)

Specifies if the input should be Jackson JsonNode or a JSON String. With Jackson, a body that is JSON text (its first non-whitespace character is \{ or ), bytes, a stream or a file is parsed as JSON, other text is a JSON string value, and any other body, such as a Map or a List, is converted by Jackson. With JsonString, the body is always parsed as JSON.

Enum values:

  • Jackson

  • JsonString

Jackson

JsonataInputOutputType

outputType (producer)

Specifies if the output should be Jackson JsonNode or a JSON String.

Enum values:

  • Jackson

  • JsonString

Jackson

JsonataInputOutputType

prettyPrint (producer)

Whether to pretty print JSon output when using string as output type.

false

boolean

lazyStartProducer (producer (advanced))

Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel’s routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing.

false

boolean

frameBinding (advanced)

To configure the Jsonata frame binding. Allows custom functions to be added.

JsonataFrameBinding

Message Body

The message body at each side of the JSONata component: Consumer is the body of the messages the consumer creates, Consumer reply the bodies a consumer that answers its caller can reply with, Producer input the bodies the producer can send or write, and Producer output the body after the producer.

Side Body Description

Producer input

map, list, pojo, text, bytes, stream or file, as json

JSON data: a Map, a List, a JsonNode or another object Jackson converts, or JSON as text, bytes, a stream or a file, which is parsed. Text that does not start with { or [ is read as one JSON string. With inputType=JsonString the body is always parsed as JSON.

  • With inputType=JsonString: text, bytes, stream or file

Producer output

pojo (com.fasterxml.jackson.databind.JsonNode), as json

The result as a Jackson JsonNode, or as JSON text with outputType=JsonString.

  • With outputType=JsonString: text (java.lang.String)

The bodies are the ones with the default options. A side that is not listed is not known, and tooling does not guess it. The carriers are described in the Camel Catalog.

Usage

Input and output types

With the default inputType, Jackson, the body can be:

  • JSON text (a String or other text whose first non-whitespace character is { or [), which is parsed as JSON;

  • bytes, an InputStream (including a stream cache) or a file (java.io.File, java.nio.file.Path or the file of the File component), which is parsed as JSON. The text is decoded in the charset of the exchange (Exchange.CHARSET_NAME) when one is set; otherwise Jackson detects the encoding;

  • any other object, such as a Map, a List or a Jackson JsonNode, which is converted by Jackson.

Text that does not start with { or [ is a JSON string value, so for example the expression $uppercase($) turns the body hello into "HELLO". Text that starts with { or [ but is not valid JSON fails with the parse error.

With inputType=JsonString, the body is always parsed as JSON.

The output is a Jackson JsonNode by default; set outputType=JsonString to get a JSON String.

Remote expressions

The expression can be loaded from an http or https URL. The options of the endpoint, such as inputType, outputType and prettyPrint, are used by the endpoint, and only the other query parameters are sent to the server. For example, jsonata:https://example.com/transform.jsonata?version=2&outputType=JsonString requests https://example.com/transform.jsonata?version=2.

Examples

Basic

For example, you could use something like:

The messages of the queue are JSON text, so the examples set inputType and outputType to JsonString: the body is always parsed as JSON, and the result is JSON text. With the default, Jackson, the result is a JsonNode.

  • Java

  • XML

  • YAML

from("activemq:My.Queue")
    .to("jsonata:com/acme/MyResponse.json?inputType=JsonString&outputType=JsonString");
<route>
  <from uri="activemq:My.Queue"/>
  <to uri="jsonata:com/acme/MyResponse.json?inputType=JsonString&amp;outputType=JsonString"/>
</route>
- route:
    from:
      uri: activemq:My.Queue
      steps:
        - to:
            uri: jsonata:com/acme/MyResponse.json
            parameters:
              inputType: JsonString
              outputType: JsonString

And a file-based resource:

  • Java

  • XML

  • YAML

from("activemq:My.Queue")
    .to("jsonata:file://myfolder/MyResponse.json?contentCache=true&inputType=JsonString&outputType=JsonString")
    .to("activemq:Another.Queue");
<route>
  <from uri="activemq:My.Queue"/>
  <to uri="jsonata:file://myfolder/MyResponse.json?contentCache=true&amp;inputType=JsonString&amp;outputType=JsonString"/>
  <to uri="activemq:Another.Queue"/>
</route>
- route:
    from:
      uri: activemq:My.Queue
      steps:
        - to:
            uri: jsonata:file://myfolder/MyResponse.json
            parameters:
              contentCache: true
              inputType: JsonString
              outputType: JsonString
        - to:
            uri: activemq:Another.Queue

Frame bindings

It is possible to configure custom functions that can be called from Jsonata. For example you might want to be able to inject environment variables:

  • Java

  • XML

  • YAML

from("activemq:My.Queue")
    .to("jsonata:file://myfolder/MyResponse.json?contentCache=true&inputType=JsonString&outputType=JsonString&frameBinding=#customBindings")
    .to("activemq:Another.Queue");
<route>
  <from uri="activemq:My.Queue"/>
  <to uri="jsonata:file://myfolder/MyResponse.json?contentCache=true&amp;inputType=JsonString&amp;outputType=JsonString&amp;frameBinding=#customBindings"/>
  <to uri="activemq:Another.Queue"/>
</route>
- route:
    from:
      uri: activemq:My.Queue
      steps:
        - to:
            uri: jsonata:file://myfolder/MyResponse.json
            parameters:
              contentCache: true
              inputType: JsonString
              outputType: JsonString
              frameBinding: "#customBindings"
        - to:
            uri: activemq:Another.Queue

A custom binding might look like the following:

Java-only: implementing a custom JsonataFrameBinding
@NoArgsConstructor
public class CustomJsonataFrameBinding implements JsonataFrameBinding {
  @Override
  public void bindToFrame(Jsonata.Frame frame) {
    frame.bind("env", (String s) -> System.getenv(s));
  }
}