Bean component
The
beancomponent calls your own Rust code, registered in the registry under a name, from a route.
Scheme: bean: · Also: class: (see class) · Crate: cameleer-core · Cargo feature: none, always included (build features) ·
Consumer: no · Producer: yes · Apache Camel: Bean
When to use it
- Put business logic (pricing, scoring, validation) in plain Rust functions and call them from YAML or Rust routes.
- Give an AI agent route a deterministic tool, such as a fraud score, that runs in-process.
- Reuse one service object with several named methods (
?method=score,?method=explain).
URI format
bean:beanName[?method=name]Example
- route:
id: score-payment
from:
uri: direct:score
steps:
- to: bean:fraudScorer?method=score
- setBody:
simple: "risk=${body}"The bean is registered from Rust before the routes start. Methods added with method_value return the
new body:
use cameleer_core::component::bean::{bind_bean, BeanMethods};
use cameleer_core::prelude::*;
pub fn register(ctx: &CamelContext) {
let scorer = BeanMethods::new()
.method_value("score", |ex: &Exchange| {
let amount: f64 = ex.body().to_string().parse().unwrap_or(0.0);
Ok(Value::from(if amount > 1000.0 { "high" } else { "low" }))
})
.method("tag", |ex: &mut Exchange| {
ex.set_header("scored", true);
Ok(())
});
bind_bean(ctx.registry(), "fraudScorer", scorer);
}Sending 2500 to direct:score returns risk=high.
Rust DSL
use cameleer_core::prelude::*;
pub fn routes(ctx: &CamelContext) -> Result<()> {
ctx.add_routes(|b| {
b.from("direct:score")
.route_id("score-payment")
.to("bean:fraudScorer?method=score")
.set_body(simple("risk=${body}"));
})
}Options
| option | default | description |
|---|---|---|
method | The method to call. score(${body}) is read as score; argument binding is up to the bean. Without it, the bean's only or default method is called. | |
scope, cache, multiParameterArray, lazyStartProducer, parameters.*, bean.* | Accepted and ignored. |
A registry entry can be:
- a
BeanMethodsvalue: named closures (methodworks on the exchange,method_valuereturns the body); - any type implementing the
Beantrait, bound withbind_bean; - a
Processorbound withRegistry::bind_processor(the method name is ignored).
Message headers
| header | direction | description |
|---|---|---|
CamelBeanMethodName | in | Overrides the method option for this message. |
Run it with Docker
Beans are Rust code, so they need a Rust program that registers them (build your own binary with
cameleer-main and call bind_bean in main.configure(...)). The stock pmsudhi/cameleer image has no
custom beans; use language or a script step there instead.
Common questions
Why do I get NoSuchBeanException?
Nothing is bound under that name in the registry. Bind it before the route first uses it.
How do I call a different method per message?
Set the header CamelBeanMethodName, for example from a choice.
What happens when the method does not exist?
The exchange fails with MethodNotFoundException, which lists the methods of the bean.
Related
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.