Claus Ibsen created CAMEL-25334:
-----------------------------------

             Summary: Content-type aware payloads for low-code: the body stays 
text with its content type, Groovy and simple read JSON fields from it, 
structured results go back to text
                 Key: CAMEL-25334
                 URL: https://issues.apache.org/jira/browse/CAMEL-25334
             Project: Camel
          Issue Type: New Feature
          Components: camel-groovy, camel-core
            Reporter: Claus Ibsen


Low-code users, and AI models writing routes, think of the payload as JSON (or 
XML, CSV, text) and write data mappings in Groovy and simple accordingly. Camel 
carries the native Java type of each component instead - a GenericFile, a 
byte[], an InputStream, a Map - and the gap shows up as runtime errors:

* Groovy {{body.find { it.sku == headers.sku } }} on JSON that was not 
unmarshalled: {{No such property: sku for class: java.lang.Byte}}
* simple {{$\{body[amount]\}}} on the file consumer's body: {{Key: amount not 
found in bean: GenericFile[...]}}
* a mapping that returns a Map, sent to an http producer: no type converter 
from LinkedHashMap to InputStream
* a jsonpath result stored in a header as a LinkedList, which disappears when 
the message crosses a JMS broker

Raymond Meester described the same from the Fluxygen low-code platform on 
Camel, where users write Groovy and simple without knowing Java: 
[Text-orientated vs. Object-orientated in 
integration|https://camel.zulipchat.com/#narrow/channel/257298-camel/topic/.E2.9C.94.20Text-orientated.20vs.2E.20Object-orientated.20in.20integration/with/568024059].
 In the local-model benchmark, 19 of 156 attempts in one series died on such a 
body type collision.

h3. Proposal: a content-type aware mode

Not "everything is text", and not a second Camel: the payload keeps its content 
type, the body stays the raw text or bytes between steps, and each language 
reads it the way it expects:

||who||what it sees when the content type is JSON||
|jsonpath, jq|the raw JSON text, as today|
|Groovy|parsed data (Map / List), so {{body.sku}}, {{body.find \{ it.sku == ... 
\}}}, {{body.items.each \{ ... \}}} work; the text stays available (for example 
as {{bodyText}})|
|simple {{$\{body[sku]\}}}, {{$\{body.sku\}}}|the field, read from the parsed 
JSON|
|producers|the text, unchanged|
|marshal json|the text, passed through (CAMEL-25329)|

The return side matters as much as the read side: a structured result (Map, 
List, JsonNode) that a language stores with setBody or setHeader becomes JSON 
text again, so the next producer, broker or mapping gets text and headers 
survive a JMS hop.

Where the content type comes from: the Content-Type header, which HTTP 
consumers and Jackson's marshal already set; for the file consumer, the file 
name through MimeTypeHelper (probeContentType); otherwise the first character 
of the text. Binary content stays binary, and a size threshold (as stream 
caching has) keeps large payloads as streams.

Groovy needs no new dependency: camel-groovy already depends on groovy-json and 
groovy-xml (JsonSlurper gives Map/List, XmlSlurper GPath for XML). Simple 
already compares text numbers numerically (ObjectHelper.typeCoerceCompare), so 
{{$\{header.qty\} > 5}} keeps working with text headers.

h3. Prototype and measurement

# Groovy, behind an option: a JSON body is bound as Map/List, the text as 
bodyText, a Map/List result goes back to JSON text.
# simple: {{$\{body[x]\}}} and {{$\{body.x\}}} read fields from JSON text.
# Headers: a structured result from any language becomes JSON text when the 
mode is on.
# Run the local-model benchmark ladder with the mode off and on and compare the 
body type collisions and pass rate before deciding on the switch (one 
camel.main property, or per language) and on defaults.

Classic routes keep the native body types; the mode is opt-in.

Related: CAMEL-24844 (body type flow), CAMEL-25330 (the Groovy hint this would 
replace with behaviour), CAMEL-25329 (marshal passes JSON text through).

_Claude Code on behalf of davsclaus_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to