7

Apache Camel offers several ways of performing data transforms: its concept of the Transform EIP, custom DataFormats, as well as its allowance for custom Type Converters.

I have a situation where I need to do a very complex transform from inside a Camel route. Should I be implementing my own Type Converter, my own DataFormat, or should I implement org.apache.camel.Expression and put all the transform stuff in there:

public class MyTransformer implements Expression {
    @Override
    public <T> T evaluate(Exchange arg0, Class<T> arg1) {
        // ...
    }
}

I guess I'm confused about where/when it's appropriate to use your own Type Converter, when to use the .transform(myTransformer) processor, or when to use a custom DataFormat. Thanks in advance!

2 Answers2

13

The differences are subtle, though they are all used for different things. You should use:

  • a transformer when you are converting a "business payload" from one shape to another. For example, when you are converting value objects that you pulled from a DAO into JAXB annotated objects that you are going to use to invoke a webservice.
  • a data format when you want to marshall an high-level representation, such as some type of Object, into a lower level representation - something that you would send over a wire. Data formats include serialization, Google protocol buffers, JSON, JAXB etc.
  • a type converter when you are changing the way you access a representation of a message. E.g. a String and a byte array or an InputStream still read the same characters, so there you might write (though there actually are built-in) converters that convert between any two of these.
Jakub Korab
  • 4,974
  • 2
  • 24
  • 34
4

Just to add what Jake said above. It all depends.

And you do not need to use any of the Camel APIs for doing that. There can be situations where you need to transform the message payload only once or few times. And for that you can use a plain POJO and invoke it from a Camel route etc

For example a method in a POJO that converts a String to a MyOrder instance.

public MyOrder doSomething(String data) {
    ...
    return ...
}

And then use a method call in the message transformer in the route

.transform().method(MyBusinessClass.class, "doSomething")

Though using any of the Camel ways for message transformation as Jake answered, allows you to integrate this seamless into Camel and use it as a first-class citizen as it was provided out of the box from Camel itself. And allows you to reuse that in other routes and Camel applications.

Implementing an org.apache.camel.Expression to transform the message payload is though not so often used. There are better ways as Jake says. Or use a POJO as shown above. Though the POJO above gets eventually evaluated as an org.apache.camel.Expression, and hence why you can implement once and use that yourself as well.

If you have a copy of Camel in Action book, then chapter 3 is all transforming data with Camel.

Claus Ibsen
  • 56,060
  • 7
  • 50
  • 65