Camunda as a term can be a little hard to pin down. It’s a company, it’s Platform, it’s a cloud service, and about 12 years ago, it was an unused .com domain that Bernd Ruecker spent good money securing. I want to return to the basics in this blog post, to share how using Camunda’s process engine in your Java application will make development easier and save you time. This is a fundamental but sometimes forgotten aspect of Camunda, given all the bells and whistles that surround it.
For clarification, when I say Camunda I’m talking specifically about the engine, a
.jar file. It’s Open Source, about four or five megabytes, and anyone can use it as you would any other project dependency, like using Maven.
<dependency> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-engine</artifactId> <version>7.16.0</version> <scope>provided</scope> </dependency>
I’m going to explain the three fundamentals of this engine while emphasizing exactly what benefits it offers to a developer who would include it in their project.
Visualization at Development and Runtime
The Camunda engine has the ability to parse and execute BPMN and DMN models. BPMN defines how the state should progress through a series of services, events and tasks. While DMN defines rules that can be executed within the context of a request in order to make a decision. In both cases, the models are directly executable and graphically represented to the user.
The most obvious benefit here is that you’re able to see and control the order of how the internal services of the application are run. Which is quite nice – you no longer have to step through various classes and methods if you want to see how things are intended to execute. Neat!
But to quote the late great Billy Mays, that’s not all! Because that same visualization is available during runtime, even when running your application you can verify what will happen as part of a running process without needing to look into the code.
The alternative to this is simply looking through the code and tracking how each service communicates with the others and then draw a nice picture representing that communication – but as you update your code that picture will need updating as well. BPMN and DMN are live documentation and any change you make to them will change the code. It’s never out of date.
Keeping State with Zero Effort
I’ve spoken before at length about the importance of adding the state to your application. And rather than once again going into details about how it makes everything more reliable across the board, I’m just going to boil it down to what seems like a simple requirement. Imagine this feature request showed up for your project:
When the application restarts or crashes, I want running requests unaffected and to be picked up where they left off.
Ok so, you add a database, then you need to periodically store the current state and the entity data. In addition, you also need to add some way of picking up the state after a restart and continuing as if nothing happened. How long would it take to implement this if I was a ticket? While you think about that, you can watch a gif of how you can do it with Camunda.
So how exactly does this fancy moving picture solve the problem? Well Camunda has a H2 database out of the box, so there’s no need for you to create one. Once you link some Java class to a task (as shown above) you can then create transaction boundaries with before or after the task – which automatically persists the data to the database in runtime.
If you restart, Camunda has a job executor that will pick up any unfinished committed state and move it along the process without you needing to code or configure anything.
That feature request would require almost no practical code change to your project.
Write Less Boilerplate Code
The most unique and important thing you’ll write in any application is business logic. That’s the Java code, services and/or front-end implementing the core functionality required by the application. Everything else facilities their execution. Often wrapped up in this business logic, is the choreography of services. This is where by calling one service you’re kicking off a chain of services before eventually returning with a result. From a development perspective, this means it needs the following implementation:
- Expose endpoint so that it can be called
- Do important calculations of some kind
- Call next service
- Wait for response
- Return result to requester
This is actually not hard to implement. It often doesn’t even require much code if you’re using the right frameworks, but think for a moment of life beyond the “Happy Path.”
- What if the “next service is down?”
- Do you want to wait for a synchronous or async response?
- What if the “next service” you call changes or becomes deprecated?
This can all be taken care of with some additional coding. But now you’ve gone into a spiral where in order to facilitate the smooth execution of your business logic, you have to spend more time writing boilerplate connective tissue than on the interesting part of your application.
So don’t do that. Just by adding a process engine you can completely forget about conflating business logic code with integration code. Anything needed to connect up your Java classes and front end integrations is taken care of and on top of that, you get centralized error handling, version control and even testing.
So going back to the list – what needs to be coded if you add a process engine?
Expose endpoint so that it can be called Do important calculations of some kind Call next service Wait for response Return res ult to requester.
Clearly this means you get to spend more time on the parts of your application with higher importance and interest.
Give It a Try
Reading is great – in fact, I fully endorse it. But when it comes to software development, getting hands on with a technology or framework will teach you a lot about how you can work with it.
So go build a quick Spring Boot project here: start.camunda.com Then feel free to explore the points I’ve brought up here.