Sometimes you have multiple services you want to call at the same time and merge their results when they’re all in (or after a timeout). In Enterprise Integration Patterns (EIP) this is a Splitter followed by an Aggregator. I wanted to try and implement this in Spring Boot using Apache Camel so I did. Since this is my first quick try at Apache Camel, I might not have followed much best practices. I used sample code from Baeldungs blog, combined it with this sample of sending parallel requests using Futures. You can browse my code here.
Run the sample
First clone https://github.com/MaartenSmeets/camel-samples.git
mvn clean package java -jar .\target\simplerouter-1.0-SNAPSHOT.jar
What does it do?
I can fire off a request to an api-splitter endpoint with a JSON message. It then calls 2 services in parallel (using separate threads) and merges their results. The combined result is returned.
It is pretty fast; response times on my laptop around 10ms.
How does it work?
Two separate services are hosted to accept requests. The api-splitter and the api itself. Of course next to the api-docs which are in Swagger v2 format so you can easily import that in a tool like Postman.
Camel uses Components. ‘http’ is such a Component and so is ‘direct’. These components have their specific configuration. There is a REST DSL available to expose endpoints and indicate which requests are accepted and should go where. The DSL can indicate to which component a request should go. ‘direct’ components can be called from the same CamelContext. Here most of the ‘heavy lifting’ happens in my example. The from and to syntax for forwarding requests is pretty straightforward and the RouteBuilder is easy to use.
There is an object available to map the JSON request to in this example. You’re not required to map the JSON to a Java object but for processing inside your Java code, this can come in handy. The api-splitter calls a direct:splitter which creates two Futures do do the calls in parallel to the local api (which maps the JSON to a Java object and does some processing). The result when received is then parsed to JSON and the results from both services are merged in a single array. Below a small picture of how this looks.
A nice first experience with Apache Camel. I was having some challenges with TypeConverters and getting the body in the correct shape/type but beyond that the experience was quite good. It is relatively easy to use (in this small scenario), integrates well with Spring Boot and my first impression is that it is quite flexible. Also the default logging provides useful information on the service call stack.
Of course what I didn’t implement was a message agostic routing mechanism and I haven’t checked what happens when one of the services doesn’t respond; you want to provide a timeout you can do so in the HTTP Component. The code around the Futures will require some nice exception handling though in order to return a nice message if one of the calls fails and the other doesn’t.