Getting started with Cameleer
Install Cameleer (Docker image,
cargo installor Rust crates), run a first route and a first REST API, and configure them with properties and environment variables, in about ten minutes.
Cameleer is Apache Camel rewritten in Rust: the same routes, endpoint URIs, Enterprise
Integration Patterns and Simple language, as one native binary with no JVM. If you know Camel,
you already know how to write Cameleer routes. Every route on this page runs in the test suite
(crates/cameleer-main/tests/docs_guides.rs).
Install
Pick one of three ways. They run the same routes.
Docker
The image pmsudhi/cameleer on Docker Hub is a single binary on a distroless base, for
linux/amd64 and linux/arm64, about 20 MB to download. Mount your route files and run them:
docker run --rm -p 8080:8080 -v "$PWD:/routes:ro" pmsudhi/cameleer run /routes/hello.camel.yamlIt runs as a non-root user, works with --read-only, and stops gracefully on SIGTERM. The
deployment guide covers Docker Compose, Kubernetes and Cloud Run.
The cameleer command line
With a Rust toolchain installed:
cargo install cameleer-main
cameleer run hello.camel.yamlThis installs the cameleer command with every component. Its subcommands follow Camel JBang (run, init, ps, stop, log, ...). To build from source:
git clone https://github.com/pmsudhi/cameleer && cd cameleer
cargo build --release -p cameleer-main
target/release/cameleer run examples/hello-api.camel.yamlRust crates
To embed routes in your own Rust program, depend on cameleer-core (the engine, EIPs and Rust
DSL) and the crates for the components you need:
[dependencies]
cameleer-core = "0.4"
cameleer-http = "0.4"cameleer-main bundles every component and runs YAML routes from Rust; see
Embed routes in a Rust program below.
Every component is included by default
The image, cargo install cameleer-main and the crates' default features contain every
component, language and data format, so any route in these docs runs without extra setup.
For a smaller binary (a serverless function, an edge device, a slim image) pick only the
families your routes use with cargo features; Build features lists them
and shows the commands. Each component page names its feature in its header line.
Your first route
A route has one input (from) and a list of steps. Save this as hello.camel.yaml:
- route:
id: hello
from:
uri: timer:hello
parameters:
period: 500
repeatCount: 3
steps:
- setBody:
simple: "Hello from Cameleer, message ${exchangeProperty.CamelTimerCounter}"
- log: "${body}"Run it with cameleer run hello.camel.yaml (or the docker run line above). The timer
endpoint fires three times, half a second apart; setBody builds a message with the
Simple language; log prints Hello from Cameleer, message 1, then 2 and 3, to standard output.
Without repeatCount the timer runs until you stop the process with Ctrl+C.
Your first REST API
The REST DSL declares HTTP endpoints and hands each request to a route. Save this as
hello-api.camel.yaml:
- rest:
path: /hello
get:
- path: /{name}
to: direct:greet
- route:
id: greet
from:
uri: direct:greet
steps:
- setHeader:
name: Content-Type
constant: application/json
- setBody:
simple: '{"greeting": "Hello, ${header.name}!"}'docker run --rm -p 8080:8080 -v "$PWD:/routes:ro" pmsudhi/cameleer run /routes/hello-api.camel.yaml
curl localhost:8080/hello/Ada # {"greeting": "Hello, Ada!"}Path parameters such as {name} become headers. The server listens on port 8080 by default
(camel.server.port changes it). For JSON binding, validation and error responses, see
examples/rest-api.camel.yaml and the
REST component.
Configuration
Routes read configuration with property placeholders, as in Camel:
{{name}}and{{name:default}}come fromapplication.properties(orapplication.yaml), environment variables and--prop name=value.{{env:NAME}}and{{env:NAME:default}}read an environment variable directly.
- route:
id: configured
from:
uri: "timer:tick?period={{tick.period:1000}}&repeatCount=1"
steps:
- setBody:
simple: "{{greeting}} from {{env:SITE_NAME:the lab}}"
- log: "${body}"With this application.properties next to the route:
greeting=Good morning
tick.period=200
camel.server.port=9090cameleer run configured.camel.yaml --properties application.properties
SITE_NAME=plant-7 cameleer run configured.camel.yaml --prop greeting=HiThe first command logs Good morning from the lab. Settings are applied in this order, the last
one winning: the properties file, CAMEL_* environment variables (CAMEL_SERVER_PORT=9090
sets camel.server.port), then --prop. Spring Boot and Quarkus names
(server.port, spring.profiles.active) and profiles (application-dev.properties) work too.
Never put secrets in route files: use {{env:...}} or a secrets vault
({{aws:...}}, {{azure:...}}, {{gcp:...}}).
Embed routes in a Rust program
The Rust DSL has the same EIPs as the YAML DSL, with Rust casing:
use cameleer_core::prelude::*;
use cameleer_http::rest::RestDslExt;
fn main() -> Result<()> {
let ctx = CamelContext::new();
cameleer_http::register(&ctx);
ctx.properties().set("camel.server.port", "8080");
ctx.add_routes(|b| {
b.rest("/api/greet").get("/{name}").to("direct:greet");
b.from("direct:greet")
.set_header("Content-Type", constant("application/json"))
.set_body(simple(r#"{"greeting": "Hello, ${header.name}!"}"#));
})?;
ctx.start()?;
loop { std::thread::park(); }
}To run YAML route files from your own binary with every component, depend on cameleer-main
and use cameleer_main::new_main(), then add_route_file("routes/hello.camel.yaml") and
run() (example).
Useful commands
| command | what it does |
|---|---|
cameleer run route.camel.yaml | run one or more route files (all route files of the current folder when none is given) |
cameleer run --dev route.camel.yaml | reload route files when they change |
cameleer init my-route.camel.yaml | write a starter route |
cameleer ps, cameleer stop --all | list and stop running integrations |
cameleer get routes, cameleer get health | inspect a running integration |
cameleer export --directory my-service | turn routes into a standalone Rust project |
cameleer catalog components | list the components |
Where to go next
- Concepts: routes, endpoints, exchanges, messages, components and the DSLs.
- Build features: a smaller build with only the components you use.
- Enterprise Integration Patterns: every EIP with a YAML and a Rust example.
- Error handling: retries, dead letter channels,
onException. - Cameleer for AI agents and Cameleer at the edge: cookbooks.
- Migrating from Apache Camel and the FAQ.
- Examples: real routes for Kafka, S3, Slack and OpenAI, each with a
docker runline.
Common questions
Do I need Java or Maven to run Cameleer?
No. Cameleer is a native binary with no JVM. You need Rust only to build it from source or to embed it; the Docker image and the installed binary need nothing else.
Can I run my existing Apache Camel YAML routes?
Mostly yes: Camel YAML and XML routes run unchanged when they use components and options Cameleer supports. Java beans and processors must be rewritten in Rust. See Migrating from Apache Camel.
How do I change the HTTP port?
Set camel.server.port: --prop camel.server.port=9090, the environment variable
CAMEL_SERVER_PORT=9090, or camel.server.port=9090 in application.properties.
Where do log messages go?
To standard output. Set the level with the CAMEL_LOG_LEVEL environment variable (TRACE,
DEBUG, INFO, WARN, ERROR or OFF).
Related
- README, deployment guide, feature list
- Apache Camel: Camel JBang, YAML DSL
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.