This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-website.git


The following commit(s) were added to refs/heads/main by this push:
     new c803b571 blog: The DNA of Apache Camel — 19 years of from().to() 
(#1629)
c803b571 is described below

commit c803b571d04f8914f912c767eabba0c5e6311ef4
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jun 12 09:53:56 2026 +0200

    blog: The DNA of Apache Camel — 19 years of from().to() (#1629)
    
    * blog: The DNA of Apache Camel — 19 years of from().to()
    
    Co-Authored-By: Claude <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
    
    * Update blog date to today and align numbers with website
    
    * Update featured SVG numbers to match blog
    
    * Fix YAML DSL examples to use canonical format
    
    * Add Camel 1.0 Tribute example section to blog
    
    * Remove horizontal rulers from Camel DNA page
    
    * Add Camel 1.0 Tribute example link to What is Apache Camel page
    
    * Revert what-is-apache-camel changes
    
    ---------
    
    Signed-off-by: Claus Ibsen <[email protected]>
    Co-authored-by: Claude <[email protected]>
---
 .../blog/2026/06/camel-dna-19-years/featured.svg   |  52 ++++
 content/blog/2026/06/camel-dna-19-years/index.md   | 339 +++++++++++++++++++++
 content/camel-dna/_index.md                        |  10 -
 3 files changed, 391 insertions(+), 10 deletions(-)

diff --git a/content/blog/2026/06/camel-dna-19-years/featured.svg 
b/content/blog/2026/06/camel-dna-19-years/featured.svg
new file mode 100644
index 00000000..7b50587a
--- /dev/null
+++ b/content/blog/2026/06/camel-dna-19-years/featured.svg
@@ -0,0 +1,52 @@
+<svg xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 1200 630">
+  <defs>
+    <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
+      <stop offset="0%" style="stop-color:#1a1a2e"/>
+      <stop offset="100%" style="stop-color:#16213e"/>
+    </linearGradient>
+    <linearGradient id="accent" x1="0%" y1="0%" x2="100%" y2="0%">
+      <stop offset="0%" style="stop-color:#e94560"/>
+      <stop offset="100%" style="stop-color:#f5a623"/>
+    </linearGradient>
+    <linearGradient id="codeGlow" x1="0%" y1="0%" x2="0%" y2="100%">
+      <stop offset="0%" style="stop-color:#64ffda;stop-opacity:0.15"/>
+      <stop offset="100%" style="stop-color:#64ffda;stop-opacity:0"/>
+    </linearGradient>
+  </defs>
+  <rect width="1200" height="630" fill="url(#bg)"/>
+  <rect x="0" y="580" width="1200" height="6" fill="url(#accent)"/>
+
+  <!-- DNA helix suggestion - two intertwining curves -->
+  <path d="M 50 200 Q 150 150, 250 200 Q 350 250, 450 200 Q 550 150, 650 200 Q 
750 250, 850 200 Q 950 150, 1050 200 Q 1150 250, 1200 200" stroke="#e94560" 
stroke-width="2" fill="none" opacity="0.3"/>
+  <path d="M 50 250 Q 150 300, 250 250 Q 350 200, 450 250 Q 550 300, 650 250 Q 
750 200, 850 250 Q 950 300, 1050 250 Q 1150 200, 1200 250" stroke="#f5a623" 
stroke-width="2" fill="none" opacity="0.3"/>
+
+  <!-- Title -->
+  <text x="600" y="160" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="64" font-weight="700" fill="#ffffff">The 
DNA of</text>
+  <text x="600" y="235" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="64" font-weight="700" 
fill="#ffffff">Apache Camel</text>
+
+  <line x1="350" y1="270" x2="850" y2="270" stroke="url(#accent)" 
stroke-width="3"/>
+
+  <!-- Code snippet - the original from().to() -->
+  <rect x="250" y="310" width="700" height="80" rx="8" fill="#0d1117" 
stroke="#30363d" stroke-width="1"/>
+  <rect x="250" y="310" width="700" height="80" rx="8" fill="url(#codeGlow)"/>
+  <text x="290" y="345" font-family="'SF Mono', 'Fira Code', monospace" 
font-size="16" fill="#8b949e">// commit 77b260b6 — March 19, 2007</text>
+  <text x="290" y="375" font-family="'SF Mono', 'Fira Code', monospace" 
font-size="18" fill="#c9d1d9">from(<tspan 
fill="#a5d6ff">"seda://a"</tspan>).<tspan fill="#d2a8ff">to</tspan>(<tspan 
fill="#a5d6ff">"seda://b"</tspan>);</text>
+
+  <!-- Stats bar -->
+  <text x="170" y="475" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="42" font-weight="700" 
fill="#e94560">42</text>
+  <text x="170" y="505" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="16" fill="#8892b0">files in commit 
#1</text>
+
+  <text x="400" y="475" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="42" font-weight="700" 
fill="#f5a623">100K+</text>
+  <text x="400" y="505" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="16" fill="#8892b0">commits today</text>
+
+  <text x="600" y="475" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="42" font-weight="700" 
fill="#e94560">350+</text>
+  <text x="600" y="505" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="16" fill="#8892b0">components</text>
+
+  <text x="800" y="475" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="42" font-weight="700" 
fill="#f5a623">19</text>
+  <text x="800" y="505" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="16" fill="#8892b0">years</text>
+
+  <text x="1020" y="475" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="42" font-weight="700" 
fill="#e94560">1</text>
+  <text x="1020" y="505" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="16" fill="#8892b0">Processor method</text>
+
+  <text x="600" y="560" text-anchor="middle" font-family="system-ui, 
-apple-system, sans-serif" font-size="20" fill="#ccd6f6">The pattern that 
survived five technology eras</text>
+</svg>
diff --git a/content/blog/2026/06/camel-dna-19-years/index.md 
b/content/blog/2026/06/camel-dna-19-years/index.md
new file mode 100644
index 00000000..4fa2df75
--- /dev/null
+++ b/content/blog/2026/06/camel-dna-19-years/index.md
@@ -0,0 +1,339 @@
+---
+title: "The DNA of Apache Camel: How a 42-File Commit Became the World's 
Integration Framework"
+date: 2026-06-12
+draft: false
+authors: [davsclaus]
+categories: ["Community"]
+keywords: ["apache camel", "history", "architecture", "integration", 
"enterprise integration patterns", "evolution", "from to", "exchange", 
"processor", "dsl"]
+preview: "On March 19, 2007, James Strachan committed 42 files with the 
message 'Initial checkin of Camel routing library.' Nineteen years and 100,000+ 
commits later, the from().to() pattern from that first test still compiles and 
runs unchanged. This is the story of the DNA that survived five technology 
eras."
+---
+
+On March 19, 2007, at 10:54 UTC, James Strachan pushed commit `77b260b6` with 
the message *"Initial checkin of Camel routing library."* It contained 42 files 
across two modules: `camel-core` and `camel-jms`.
+
+Nineteen years later, the repository has crossed **100,000+ commits** from 
**1,600+ contributors**, ships **350+ integration components**, and runs in 
production from CERN's Large Hadron Collider to UPS processing tens of billions 
of messages per day.
+
+Through all of that — through the rise and fall of ESBs, the 
SOA-to-microservices migration, the cloud-native revolution, Kubernetes, 
serverless, and now AI coding agents — the core DNA has remained remarkably 
stable. Let's trace it through the source code.
+
+## The First Test Ever Written
+
+The very first test in the very first commit:
+
+```java
+// March 19, 2007 — commit 77b260b6
+public void testSimpleRoute() throws Exception {
+    RouteBuilder builder = new RouteBuilder() {
+        public void configure() {
+            from("seda://a").to("seda://b");
+        }
+    };
+}
+```
+
+That `from().to()` — the vertebral column of every Camel route ever written — 
was there from the very first commit. So was the content-based router:
+
+```java
+// Also March 19, 2007 — same commit
+public void testSimpleRouteWithChoice() throws Exception {
+    RouteBuilder builder = new RouteBuilder() {
+        public void configure() {
+            from("seda://a").choice()
+                .when(headerEquals("foo", "bar")).to("seda://b")
+                .when(headerEquals("foo", "cheese")).to("seda://c")
+                .otherwise().to("seda://d");
+        }
+    };
+}
+```
+
+Nineteen years later, both of these still compile and run. That's the DNA.
+
+## The Original Interfaces
+
+The core abstractions were remarkably small. Here's the *entire* 
`Processor.java` from that first commit:
+
+```java
+public interface Processor<E> {
+    void onExchange(E exchange);
+}
+```
+
+One method. That's it.
+
+The *entire* `Exchange.java`:
+
+```java
+public interface Exchange<M> {
+    <T> T getHeader(String name);
+    void setHeader(String name, Object value);
+    Map<String,Object> getHeaders();
+    M getRequest();
+    M getResponse();
+    M getFault();
+    Exception getException();
+    void setException(Exception e);
+}
+```
+
+Eight methods. Headers as a `Map<String, Object>`. Request/response/fault 
message pattern. Exception handling. Everything you need to carry a message 
through a processing pipeline, nothing you don't.
+
+And `Endpoint.java`:
+
+```java
+public interface Endpoint<E> {
+    String getEndpointUri();
+    void send(E exchange);
+    E createExchange();
+}
+```
+
+Three methods. An identity (the URI), a way to send, and a way to create an 
exchange.
+
+`Component.java` was added 8.5 hours later with the commit message *"Lets add 
a component interface.. we can flesh it out later."* It was an empty marker 
interface. There was no `CamelContext` yet (that came as `CamelContainer`), no 
`Producer`, no `Consumer`, no XML DSL. Just a Java fluent builder, an exchange, 
a processor, and endpoints.
+
+## What Survived, What Evolved
+
+Today, almost two decades later, those interfaces have matured — but the shape 
is unmistakable:
+
+| Concept | 2007 | 2026 |
+|---------|------|------|
+| **Processor** | `void onExchange(E exchange)` | `void process(Exchange 
exchange)` — now `@FunctionalInterface` |
+| **Exchange** | generic `Exchange<M>`, request/response/fault | non-generic, 
unified `getMessage()`, plus variables since 4.4 |
+| **Endpoint** | had `send()` directly | factory for `Producer`/`Consumer` 
(split added weeks later) |
+| **Component** | empty marker interface | factory of Endpoints, lifecycle, 
property configurers |
+| **Route DSL** | `from("seda://a").to("seda://b")` | 
`from("seda://a").to("seda://b")` — **identical** |
+
+The method name changed from `onExchange` to `process`. The generics were 
removed. The endpoint's `send()` was factored into a dedicated `Producer` 
interface. But the fundamental shape — **a processor receives an exchange, a 
route chains processors between endpoints** — never changed.
+
+Here's `Processor.java` today:
+
+```java
+@FunctionalInterface
+public interface Processor {
+    void process(Exchange exchange) throws Exception;
+}
+```
+
+Still one method. Now it's a `@FunctionalInterface`, so you can write 
processors as lambdas. The DNA is the same; the language features caught up.
+
+## The Architecture in One Sentence
+
+If you understand this sentence, you understand Camel:
+
+> A **Route** consumes messages from an **Endpoint** via a **Consumer**, wraps 
each message in an **Exchange**, passes it through a chain of **Processors**, 
and delivers it to one or more **Endpoints** via **Producers**.
+
+Every component — whether it's JMS (2007), Kafka (2014), or LangChain4j (2024) 
— plugs into this model by implementing an `Endpoint` that creates a `Producer` 
and/or `Consumer`. The 350+ components are 350+ implementations of the same 
three interfaces.
+
+## The Five Eras
+
+### Era 1: SOA and the ESB Age (2007–2011)
+
+**The world:** ESBs ruled enterprise integration. ServiceMix, Mule, BizTalk. 
SOAP, WS-\*, JBI. Everything was XML configuration and heavyweight application 
servers.
+
+**What Camel did:** Offered a lightweight alternative. The Java DSL was a 
radical departure from XML-configured ESBs. JMS shipped in the first commit 
alongside `camel-core`. HTTP appeared 3 days later. ActiveMQ followed in May 
2007.
+
+The Enterprise Integration Patterns from Hohpe and Woolf's 
[book](https://www.enterpriseintegrationpatterns.com/) mapped perfectly to the 
`Processor` chain. Every pattern — splitter, aggregator, content-based router, 
wire tap — was just a `Processor` that manipulated an `Exchange`. The component 
model meant adding JBI, CXF, or SOAP support didn't require touching the core.
+
+**Camel 1.0** shipped January 2009. **Camel 2.0** followed just 7 months later 
in August 2009. The 2.x line would run for a decade — 26 minor releases.
+
+### Era 2: Cloud and Big Data (2011–2018)
+
+**The world:** AWS, Hadoop, Kafka, microservices. The 
monolith-to-microservices migration. Docker. Spring Boot. REST APIs replacing 
SOAP.
+
+**Key arrivals:**
+- AWS components: 2011
+- Kafka: February 2014
+- Spring Boot: October 2014
+- Kubernetes: September 2015
+
+Camel kept the same `from().to()` DNA but extended the component catalog 
massively. A route that read from JMS and wrote to a file in 2007 looked 
structurally identical to a route reading from Kafka and writing to S3 in 2015:
+
+```java
+// 2007 pattern
+from("jms:orders").to("file:processed");
+
+// 2015 pattern — same DNA
+from("kafka:orders").to("aws-s3:processed-bucket");
+```
+
+Spring Boot auto-configuration meant Camel could start in seconds instead of 
minutes inside an app server. But `RouteBuilder.configure()` was unchanged.
+
+### Era 3: Cloud-Native and Kubernetes (2018–2022)
+
+**The world:** Kubernetes became the deployment platform. Quarkus and GraalVM 
promised instant startup. Serverless. Event-driven architectures.
+
+**The big architectural split — Camel 3.0 (November 2019):**
+
+The `camel-core` monolith was split into `camel-api`, `camel-support`, 
`camel-core-model`, `camel-core-engine`, and more. This was the most 
significant internal restructuring in the project's history — but the public 
API barely changed. The `from().to()` pattern survived intact.
+
+Key innovations of this era:
+
+**Endpoint DSL** (June 2019) brought type-safe route building with IDE 
auto-completion:
+```java
+from(kafka("orders").brokers("localhost:9092"))
+    .to(aws2S3("my-bucket"));
+```
+
+**YAML DSL** (February 2021) made routes declarative configuration:
+```yaml
+- route:
+    from:
+      uri: kafka:orders
+      steps:
+        - to:
+            uri: aws2-s3:my-bucket
+```
+
+Both compile down to the same `Route` -> `Processor` chain -> `Exchange` flow. 
The YAML DSL is syntactic sugar over `ProcessorDefinition` and 
`RouteDefinition` — the same model classes that backed the Java DSL since 2007.
+
+### Era 4: Jakarta and the Modern Runtime (2023–2024)
+
+**Camel 4.0** (August 2023) made the `javax.*` to `jakarta.*` namespace 
migration and established Java 17 as the baseline. The `getOut()` method on 
Exchange, deprecated since 3.0, was finally guided toward `getMessage()`. 
Variables were added to the Exchange in 4.4, giving routes a scratchpad that 
survived across `enrich()` and `pollEnrich()` calls without header pollution.
+
+Today's Exchange still has the original methods from 2007 — just refined:
+
+```java
+exchange.getMessage().getBody();        // was: exchange.getRequest()
+exchange.getMessage().getHeader("foo"); // was: exchange.getHeader("foo")
+exchange.getException();                // unchanged since commit #1
+exchange.getVariable("myVar");          // since 4.4
+```
+
+### Era 5: AI Agents and the Machine-Readable Framework (2024–present)
+
+**The world:** LLMs, AI coding agents, MCP servers, agentic workflows. 
LangChain4j components arrived in March 2024.
+
+Why the DNA matters now more than ever: AI agents read and write code. The 
`from().to()` pattern is one of the most learnable DSLs in existence — an AI 
agent can generate a Camel route with minimal context. The YAML DSL is 
structured data that machines parse trivially. The 350+ components are a 
catalog of pre-built integrations that an agent can compose without writing 
HTTP clients or SDK boilerplate.
+
+The same pattern from commit `77b260b6`:
+
+```java
+from("seda://a").to("seda://b");
+```
+
+Today, an AI agent writes:
+
+```yaml
+- route:
+    from:
+      uri: langchain4j-chat:myModel
+      steps:
+        - to:
+            uri: kafka:ai-responses
+```
+
+Different era. Same DNA.
+
+## Then and Now: Side by Side
+
+Here is the content-based router from 2007 and its equivalent in every DSL 
available today:
+
+**2007 — Java DSL (the original)**
+```java
+from("seda://a").choice()
+    .when(headerEquals("foo", "bar")).to("seda://b")
+    .when(headerEquals("foo", "cheese")).to("seda://c")
+    .otherwise().to("seda://d");
+```
+
+**2026 — Java DSL (modern)**
+```java
+from("direct:orders").choice()
+    .when(header("type").isEqualTo("priority")).to("kafka:priority-orders")
+    .when(header("type").isEqualTo("bulk")).to("kafka:bulk-orders")
+    .otherwise().to("kafka:standard-orders");
+```
+
+**2026 — YAML DSL**
+```yaml
+- route:
+    from:
+      uri: direct:orders
+      steps:
+        - choice:
+            when:
+              - expression:
+                  simple: "${header.type} == 'priority'"
+                steps:
+                  - to:
+                      uri: kafka:priority-orders
+              - expression:
+                  simple: "${header.type} == 'bulk'"
+                steps:
+                  - to:
+                      uri: kafka:bulk-orders
+            otherwise:
+              steps:
+                - to:
+                    uri: kafka:standard-orders
+```
+
+**2026 — Endpoint DSL (type-safe)**
+```java
+from(direct("orders")).choice()
+    .when(header("type").isEqualTo("priority")).to(kafka("priority-orders"))
+    .when(header("type").isEqualTo("bulk")).to(kafka("bulk-orders"))
+    .otherwise().to(kafka("standard-orders"));
+```
+
+**2026 — Lambda route builder (one-liner setup)**
+```java
+RouteBuilder.addRoutes(context, rb ->
+    rb.from("direct:orders").choice()
+        .when(header("type").isEqualTo("priority")).to("kafka:priority-orders")
+        .when(header("type").isEqualTo("bulk")).to("kafka:bulk-orders")
+        .otherwise().to("kafka:standard-orders"));
+```
+
+Four syntaxes. One DNA. The route is always a graph of processors connected by 
endpoints, with an exchange carrying the message through.
+
+## The Numbers
+
+| Metric | Day 1 (2007) | Today (2026) |
+|--------|--------------|--------------|
+| Files | 42 | 56,000+ |
+| Components | 2 (SEDA, JMS) | 350+ |
+| DSLs | Java only | Java, YAML, XML, Endpoint DSL |
+| Core interfaces | 3 (Processor, Exchange, Endpoint) | Same 3, plus Producer, 
Consumer, Component |
+| Processor methods | 1 | 1 |
+| Contributors | 1 | 1,600+ |
+| Commits | 1 | 100,000+ |
+| Major versions | 0 | 4 (1.x through 4.x) |
+
+## Try the Original Route Today
+
+The very first Camel example ever shipped — `camel-example-jms-file` from 
Camel 1.0 — consumed messages from a JMS queue and saved them to the file 
system. Back then it was 40+ lines of Java, an embedded ActiveMQ broker, manual 
`ConnectionFactory` wiring, and a Maven project.
+
+Today, the same example is a single YAML file and one command:
+
+```bash
+camel run *
+```
+
+```yaml
+- route:
+    id: jms-to-file
+    description: "Camel 1.0 tribute: consume from JMS queue and save to file"
+    from:
+      uri: jms
+      parameters:
+        destinationName: test.queue
+      steps:
+        - log:
+            message: "Received: ${body}"
+        - to:
+            uri: file
+            parameters:
+              directoryName: test
+```
+
+No Maven project. No manual component wiring. No embedded broker — just `camel 
infra run artemis` to start one in a container. The route reads from 
`jms:queue:test.queue` and writes to `file://test`, exactly like the original.
+
+[Run the Camel 1.0 Tribute example 
→](https://github.com/apache/camel-jbang-examples/tree/main/camel-1-tribute)
+
+## Why It Lasted
+
+Most frameworks from 2007 are gone. The ones that survived bet on the right 
abstraction level. Camel bet that **integration is a graph of processors 
connected by endpoints, with an exchange carrying the message through** — and 
that bet paid off across J2EE application servers, ESBs, Spring Boot 
microservices, Kubernetes operators, serverless functions, and now AI agents.
+
+The `from().to()` pattern is Camel's `SELECT * FROM`. It's so fundamental that 
every technology era just provides new things to put inside the parentheses. 
The DNA doesn't change. The components do.
+
+Camel is approaching 20 years. Looking back through the git history, the most 
striking thing isn't how much has changed — it's how much hasn't. The first 
test James Strachan wrote on that March morning in 2007 still reads like 
idiomatic Camel. That's not an accident. That's good architecture.
diff --git a/content/camel-dna/_index.md b/content/camel-dna/_index.md
index a5f29aa2..f83eefa5 100644
--- a/content/camel-dna/_index.md
+++ b/content/camel-dna/_index.md
@@ -50,8 +50,6 @@ from("test-jms:queue:test.queue").to("file://test");
 
 One line. Take data from here, send it there. That's the DNA.
 
----
-
 ## Where Camel came from
 
 Camel was born inside the Apache ActiveMQ project. The 1.0 README was signed 
*"The Apache ActiveMQ team"*. The website lived at `activemq.apache.org/camel`. 
The Spring XML namespace was `http://activemq.apache.org/camel/schema/spring`. 
The bug tracker was `issues.apache.org/activemq/browse/CAMEL`.
@@ -68,8 +66,6 @@ This simple pipeline model turned out to be powerful enough 
to express any integ
 
 The `from().to()` syntax is the user-facing expression of this architecture. 
But underneath, it's always been endpoints and processors — a design so 
composable that it scaled from 19 components to 350+ without ever needing to 
change the core model.
 
----
-
 ## That same route today
 
 Nearly two decades later, the same JMS-to-File route looks like this:
@@ -97,8 +93,6 @@ camel run jms-to-file.camel.yaml
 
 No Maven project. No build step. No manual wiring. Just one YAML file and one 
command.
 
----
-
 ## What changed, what didn't
 
 | | **Camel 1.0** (2007) | **Camel CLI** (today) |
@@ -120,8 +114,6 @@ The core routing idea — take data from here, transform it 
if needed, send it t
 
 Some ideas are so right that they never need to change. SQL gave us `SELECT * 
FROM` over 50 years ago — and it's still the way the world queries data. 
Camel's `from().to()` is the same kind of idea. A syntax so natural that it 
reads like intent, not code. The ecosystem around it grew enormously — 
databases, cloud services, AI, containers — but the core abstraction endured 
because it matched how people actually think about moving data.
 
----
-
 ## Try the tribute example
 
 We recreated the original Camel 1.0 example as a modern Camel CLI example. Run 
it yourself:
@@ -138,8 +130,6 @@ It sends 10 test messages to a JMS queue and saves them to 
files — exactly lik
 
 [See the tribute example on GitHub 
→](https://github.com/apache/camel-jbang-examples/tree/main/camel-1-tribute)
 
----
-
 ## The DNA
 
 SQL has `SELECT * FROM`. Camel has `from().to()`.

Reply via email to