An example to show how you could use clean architecture and DDD elements with Camunda.

Overview

Camunda DDD and Clean Architecture

An example to show how you could use clean architecture and DDD and their advantages with Camunda.

I also wrote a blog post to show how clean architecture could help you to update to Camunda Platform 8 without touching your domain centered code: How Clean Architecture helps you migrating Camunda Platform 7 to 8.

🚀 Features

The BPMN process which start a second process via message correlation should represent a tiny business process just to demonstrate the architecture.

🛫 Start the process

With the following POST request, you could start the process:

curl --request POST \
  --url http://localhost:8080/loan/agreement/1 \
  --header 'Content-Type: application/json' \
  --data '
  "customerNumber": "A-11",
  "name": "Tester",
  "mailAddress": "[email protected]",
  "amount": 1100
}'

Using the admin user (username: admin and password: pw) you could log in to the Camunda Cockpit.

↔️ Migration to Camunda Platform 8

All necessary change to upgrade from Camunda Platform 7 to 8 are shown in this pull request. The only changed files are all placed in the adapter layer. So the domain does not need to be touched to change a framework.

🏗 Architecture

The following sections contain some small aspects explaining the advantages of Domain-driven Design (DDD) and clean architecture.

Flexibility around your domain (e.g., switching from Camunda 7 to Camunda 8) is the main focus I want to show you in this little example.

Clean Architecture

A software architecture that integrates changeability in their package and class structure makes it easy to switch or migrate a framework. So the migration of Camunda Platform 7 to 8 is much less painful with a good architecture.

DDD-Clean-Architecture The layers of clean architecture (based on Clean Architecture by Robert C. Martin)

Robert C. Martin describes architectural guidelines in his book "Clean Architecture", which should allow independence of frameworks, databases, user interface (UI) and other technologies. In his opinion, clean architecture ensures the testability of business rules by its design. The image above displays layers as concentric circles wrapping each other. Each layer represents different parts of software. The center of the circle represents "policies" and thus your business rules and domain knowledge. The outer circles are "mechanisms" supporting our domain center. Beside the layers, the arrows show the dependency rule – only inward point dependencies! To reach the goals of clean architecture, the domain code must not have any dependencies pointing outwards. Instead, all dependencies point towards the domain code. The essential aspect of your business domain is placed in the core of the architecture: the entities. They are only accessed by the surrounding layer: the use cases. Services in a classic layered architecture represent use cases in a clean architecture, but these services should be more fine-grained so that they have only one responsibility. You do not want one big service implementing all your business use cases. Supporting components are placed around the core (your entities and use cases), such as persistence or user interfaces.

Dependency Inversion Principle

When the dependency rule is applied, the domain has no knowledge about how you persist your data or how you display them in any client. The domain should not contain any framework code (arguably Dependency Injection). As I already mentioned, you could use the Dependency Inversion Principle (DIP) to apply the dependency rule of clean architecture. The DIP tells you to reverse the direction of a dependency. You may be thinking of the Inversion of Control (IoC) design pattern, which is not the same as DIP, although they fit well together. If you want to know the exact differences I recommend reading Martin Fowlers article "DIP in the Wild" (in short: "[...] IoC is about direction, and DIP is about shape."). The following figure shows an example of how the DIP works.

With and without Dependency Inversion Principle The Dependency Inversion Principle (DIP)

Imagine having a service (DomainService in the image) which starts a Camunda Process. To isolate your service (your business logic) from the framework, you could create another service using the Camunda Java API to start a process instance. The left frame of the image shows this scenario without applying the DIP. The domain service calls the ProcessEngineService directly. So what's the problem? Starting a process is a core aspect of our domain, so we want to pull it into our domain. By doing so, we break the rule of keeping our domain framework-agnostic. We can fix this, by placing an interface in our domain core instead of the concrete implementation and place the actual implementation outside of our domain layer, et voilà we apply the DIP.

Combining the DIP with the Ports and Adapters architecture (the clean architecture emerged of), we get the picture shown below.

DIP, Ports and Adapter, Clean Architecture Clean architecture DIP and ports and adapters

Separating our ports / use cases and adapters that drive our application (input-ports) or are driven by our application (output-ports) helps us to structure our code even more and to keep the boundaries more clear.

Mapping between layers

The following image shows how the layers interact with the domain object with and without mapping. Without mapping, you miss the biggest advantage of clean architecture: decoupling your domain core with the outer (infrastructure) layers. If you do not map between your inner and outer layers, you are not isolated. If a third-party system changes its data model, your domain model needs to change as well. To prevent dependence on external influencing factors and to promote independence and decoupling, it is necessary to map between the layers. Using the input and output ports (use case layer) as gatekeepers into your domain core, they define how to communicate and interact with your application. They provide a clear API and by mapping into your domain you keep it independent of any framework or technology model changes.

With and without mapping between layers With and without mapping between layers

The frame explaining the mapping approach is just one possible way of mapping. If you want to know more about different stages of mapping, take a look a Tom Hombergs book "Get Your Hands Dirty on Clean Architecture", he explains them pretty well. In conclusion, mapping can be used to achieve greater decoupling. On the other hand, mapping between each layer could produce a lot of boilerplate code, which might be overkill depending on your use case and the goals you are working towards.

Domain-driven Design

Using clean architecture as architecture style combines perfectly with Domain-driven Design because we completely focus on our domain core (entities and use cases). In my opinion, Domain-driven Design (DDD) perfectly combines with clean architecture due to the fact that DDD is focused on your business domain. Focusing on your domain is supported by the goal of clean architecture, keeping the domain free of any framework or technologies. E.g. your domain does not focus on how to persist something, it just tells the outgoing port to save it. The implementation of the port (placed on the adapter layer) decides to use, e.g., relational or non-relational databases.

Beside the matching goal of DDD and clean architecture, DDD tries to help you build complex designs around your domain, by e.g., building immutable objects that know all about their invariants, which helps you even more to structure your code.

DDD Elements like Aggregate Entities and ValueObject can be found in our domain-primitives library.

Structuring your code functional and brining more context to your object with, e.g. Value Object does not only help you to keep your code expressive, it also helps keeping it close to your business as your BPMN model.

🙏🏼Credits

Thanks to Matthias Eschhold for the passionate discussion around DDD and clean architecture. Matthias published a nice blog series: Clean Architecture and flexibility patterns

📨 Contact

If you have any questions or ideas, feel free to contact me or create an issue.

You might also like...

Community extension to generate a Java client from the provided Camunda 7 OpenAPI descitpion and also warp it into Spring Boot

Camunda Engine OpenAPI REST Client Java and Spring Boot This community extension is a convenience wrapper around the generated Java client from the Ca

Dec 28, 2022

A fun way to learn Camunda and win a small price

A fun way to learn Camunda and win a small price

Camunda-Coding-Challenge A fun way to learn about Camunda and win a small prize. The coding challenge is designed for the Camunda Code Studio. Results

Oct 2, 2021

SpringBoot SpringSecurity Jpa mybatis-plus websocket Redis camunda Vue3 Vite ant-design VbenAdmin vxe-table bpmn.js

SpringBoot SpringSecurity Jpa mybatis-plus websocket Redis camunda Vue3 Vite ant-design VbenAdmin vxe-table bpmn.js

Dec 13, 2022

Spring Boot Login and Registration example with MySQL, JWT, Rest Api - Spring Boot Spring Security Login example

Spring Boot Login and Registration example with MySQL, JWT, Rest Api - Spring Boot Spring Security Login example

Spring Boot Login example with Spring Security, MySQL and JWT Appropriate Flow for User Login and Registration with JWT Spring Boot Rest Api Architect

Jan 5, 2023

Spring Boot Security Login example with JWT and H2 example

 Spring Boot Security Login example with JWT and H2 example

Spring Boot Security Login example with JWT and H2 example Appropriate Flow for User Login and Registration with JWT and HttpOnly Cookie Spring Boot R

Dec 21, 2022

This module explains about the example of Spring MVC + Database Integration with MySQL using Hibernate ORM with practical coding example and required JAR dependencies

SpringMVC-Database-Integration This module explains about the example of Spring MVC + Database Integration with MySQL using Hibernate ORM with practic

Nov 2, 2021

A Java agent that disables platform features you don't use, before an attacker uses them against you.

aegis4j Avoid the NEXT Log4Shell vulnerability! The Java platform has accrued a number of features over the years. Some of these features are no longe

Jan 11, 2022

Buildable src reconstructed from the clean Phobos 1.9.0 jar

CLEAN_Phobos_1.9.0-BUILDABLE-SRC Buildable src reconstructed from the clean Phobos 1.9.0 jar. Full buildable and functional, jar in releases is built

Dec 28, 2022

Phobos 1.9.0 Clean Buildable SRC.

Phobos 1.9.0 Clean Buildable SRC.

[CLEAN] Phobos 1.9.0 Buildable SRC & Release This source has been checked by two people, myself and a friend. My friend did not find anything as he br

Dec 17, 2022
Comments
  • Migrating to Camunda 8

    Migrating to Camunda 8

    This pull request should show of using clean architecture and DDD to keep you domain clean, so a migration, e.g. to Camunda 8 only effects your adapter layer.

    opened by lwluc 1
Owner
Luc Weinbrecht
🤖💯
Luc Weinbrecht
参考 DDD/Clean Architecture 设计理念,整合 Spring Boot/Spring Security/Mybatis Plus/Vavr 的 Spring Realworld 应用案例

Demo · 更多项目 · 参考资料 ms-spring-ddd-examples Unified Domain-driven Layered Architecture for MicroService Apps,试图探索一套切实可行的应用架构规范,可以复制、可以理解、可以落地、可以控制复杂性的指导

王下邀月熊 19 Sep 23, 2022
This project was created as a simple example to show how we can implement the hexagonal architecture(software design) proposed by Netflix.

Netflix Hexagonal Architecture Table of contents About the project Description Built with Installation Requirements to run Usage information Run Licen

José Lucas 12 Dec 20, 2022
A React Native project starter with Typescript, a theme provider with hook to easy styling component, a folder architecture ready and some configs to keep a codebase clean.

React Native Boilerplate Folder structure : src ├── assets │   ├── audios │   ├── fonts │   ├── icons │   └── images ├── components │   ├── Layout.tsx

LazyRabbit 23 Sep 1, 2022
This project illustrates TDD & Clean Architecture implementation in Java

Banking Kata - Java Overview This project illustrates TDD & Clean Architecture implementation in Java, showing the Use Case Driven Development Approac

Valentina Cupać 191 Dec 28, 2022
Spring Boot Clean Architecture - Iran Plate

Spring Boot Clean Architecture Sample Iran Plate Location Finder I used the Clean Architecture in my project. In this method we can develop our projec

Mahdi Amirabdolahi 4 Jul 6, 2022
This is an example of how conditional events can be triggered in Camunda using a simple spring boot project

Camunda Conditional Events Example This example is a Spring Boot Application using Camunda. In this example i'll show a variety of ways that BPMN's Co

Niall 5 Sep 30, 2021
The goal of this topic is learning OOP principles in Java and modifying elements in 2D arrays.

Homework #11 Table of Contents General Info Technologies Used Project Status Contact General Information Homework contains two topics: Generating rand

Mykhailo 1 Feb 2, 2022
以教学为目的的电商系统。包含ToB复杂业务、互联网高并发业务、缓存应用;DDD、微服务指导。模型驱动、数据驱动。了解大型服务进化路线,编码技巧、学习Linux,性能调优。Docker/k8s助力、监控、日志收集、中间件学习。前端技术、后端实践等。主要技术:SpringBoot+JPA+Mybatis-plus+Antd+Vue3。

简介 bcMall 是一个以教学为目的的电商系统。bcMall将为你展现一个典型的系统演进过程,所使用的主流技术完全开放。 它包含ToB复杂业务、互联网高并发业务、缓存应用;DDD、微服务指导。模型驱动、数据驱动。了解大型服务进化路线,编码技巧、学习Linux,性能调优。Docker/k8s助力、监

xjjdog 411 Jan 3, 2023
Design Patterns: Elements of Reusable Object-Oriented Software

GoF Design Patterns Design Patterns: Elements of Reusable Object-Oriented Software Task 싱글톤패턴 싱글톤 패턴 구현 방법을 깨뜨리는 방법 리플렉션을 통해 싱글톤 패턴을 깨뜨리다 역직렬화를 통해 싱글톤

전지환 11 Jul 19, 2022
Application developed during the DDD training with 6 students.

Easyorder Application developed during the DDD training with 6 students. MongoDB To start MongoDB, use docker: docker run -p 27017:27017 --name mongo

RUARO Thibault 1 Jan 21, 2022