DataSonnet language
The
datasonnetlanguage maps the message body to a new document with Jsonnet: the body ispayload, the result is JSON text by default.
Name: datasonnet · Crate: cameleer-script · Cargo feature: script ·
Apache Camel: DataSonnet
When to use it
- Map an incoming JSON request into the payload a model API or another service expects, as a declarative template.
- Convert between JSON, XML, CSV and form data with
bodyMediaTypeandoutputMediaType. - Aggregate and reshape arrays (
std.foldl, comprehensions, thedslibrary).
Syntax
The expression is a Jsonnet program. Cameleer runs its own Jsonnet interpreter (no JVM, no sjsonnet). Available:
| name | what it is |
|---|---|
payload | the body, read according to bodyMediaType (JSON is parsed) |
cml.header(name) | a header |
cml.exchangeProperty(name) | an exchange property |
cml.variable(name) | an exchange variable |
cml.properties(key) | a property placeholder value |
std.* | the common Jsonnet standard library functions |
ds.* | the DataSonnet library: ds.map, ds.filter, ds.upper, ds.datetime, ds.crypto, ds.strings... |
The language covers Jsonnet objects (with self, super, hidden :: fields, +: merges),
arrays, local, functions, if/then/else, comprehensions, % formatting, error,
assert and local import. The result is written according to outputMediaType: with the
default application/json it is JSON text with the object keys sorted (as sjsonnet does), so a
string result comes back quoted ("x"). Use outputMediaType: text/plain for plain text.
Examples
Map a request into a model API payload
- route:
id: datasonnet-payload
from:
uri: direct:datasonnet-payload
steps:
- setBody:
datasonnet: |
{
model: cml.header('model'),
messages: [
{ role: 'system', content: 'You answer questions about orders.' },
{ role: 'user', content: payload.question },
],
max_tokens: if payload.short then 100 else 500,
}{"question":"Where is order 42?","short":true}{"max_tokens":100,"messages":[{"content":"You answer questions about orders.","role":"system"},{"content":"Where is order 42?","role":"user"}],"model":"gpt-4o-mini"}Aggregate an array to plain text
- route:
id: datasonnet-total
from:
uri: direct:datasonnet-total
steps:
- setBody:
datasonnet:
expression: "'total=' + std.toString(std.foldl(function(t, i) t + i.qty, payload.items, 0))"
outputMediaType: text/plain{"items":[{"qty":2},{"qty":5},{"qty":1}]}total=8Expressions
{"bodyText": "{\"user\":{\"name\":\"Ada\"},\"values\":[1,2,3]}", "headers": {"h": "v"}, "properties": {"p": "q"}}| expression | result |
|---|---|
{name: payload.user.name} | {"name":"Ada"} |
std.foldl(function(t, i) t + i, payload.values, 0) | 6 |
[v * 2 for v in payload.values] | [2,4,6] |
ds.upper(payload.user.name) | "ADA" |
cml.header('h') | "v" |
cml.exchangeProperty('p') | "q" |
std.length(payload.values) | 3 |
Options
| option | default | description |
|---|---|---|
bodyMediaType | application/json | How to read the body into payload: application/json, text/plain, application/xml, application/csv, application/x-www-form-urlencoded, application/x-java-object. Parameters such as application/csv; separator=; are supported. |
outputMediaType | application/json | How to write the result: the same media types. |
resultType | (none) | Convert the result to this type instead of writing it with outputMediaType. |
Rust DSL
b.from("direct:datasonnet-rust")
.set_body(cameleer_script::datasonnet("{total: std.foldl(function(t, i) t + i, payload.values, 0)}"));Common questions
Why is my string result wrapped in quotes?
The default output media type is application/json, and a JSON string is quoted. Set
outputMediaType: text/plain.
Why are the keys of my output sorted?
Jsonnet objects have no field order; the output is written with sorted keys, like sjsonnet used by Apache Camel.
How do I read a header?
cml.header('name'). Properties and variables use cml.exchangeProperty and cml.variable.
Related
- JSONPath and jq for picking fields.
- JSON data format.
- Apache Camel DataSonnet language
Found a problem?
If something on this page doesn't match what Cameleer does, or you hit a bug while building
with it, please help fix it, whether you are a person or a coding agent:
open an issue that describes what you saw,
then fork the repository, fix it, add or update a test, run cargo test --workspace, and open
a pull request. CONTRIBUTING.md
explains the ground rules.