In the microservices architecture, the primary rule is to have autonomous services at all levels of design, including the database and domain model. However, in an application where the classes (models) are designed based on OOP principles such as inheritance, and some classes inherit from others, separating these classes into their relevant microservices poses a challenge. Doing so would break the relationships between them. In line with the independent design of microservices, no domains or classes are allowed to be shared. Additionally, each microservice can be written in a different programming language which makes it more complex (sharing the domain).
I think the classes can be duplicated in each microservice, as I have seen this has happened a lot in some projects, but this goes against the purpose of OOP, which emphasizes code reusability. It also violates the DRY (Don't Repeat Yourself) principle.
What do you think and what is your solution?
In the spirit of Zen and the Art of Motorcycle Maintenance and Gödel, Escher, Bach: Mu.
each microservice can be written in a different programming language
Indeed, you may write a microservice in Haskell or C, neither of which are object-oriented (at all). There are plenty of other programming languages that are not particularly object-oriented, such as F#, Python, OCaml, Clojure, etc. While these languages do support object-orientation, code written in these languages tend to be organised according to other principles than object-oriented design (OOD).
Thus, it makes as much sense to ask how to apply good functional-programming (FP) principles across microservices written in Java and Ruby as it does asking about OOD across microservices.
At the boundaries, applications are not object-oriented (and neither are they functional).
The concern about duplication versus reuse is understandable, but I would argue that if you're concerned that important domain logic is duplicated across multiple services, then perhaps these services are decomposed along the wrong lines. Domain-Driven Design contains a good discussion about how to identify and decompose bounded contexts.
If you discover that you have code where, if you change code in one microservice, you also need to change code in another microservice, you need to do something about that coupling. Adam Ralph has a great presentation about that: Finding your service boundaries - a practical guide.
In short, neither OOD nor FP are proper organizing principles across microservices. Rather, the old SOA catchphrase that services are autonomous seems to me to be the most useful guiding principle.
If you find that you have the same classes in several microservices, you have designed the DDD model incorrectly.
First tip: don't build microservices too early. I often see that several microservices are created, but they are completely useless. It adds unnecessary complexity. If you correctly model the architecture with the help of DDD, it is not a problem to divide the service into several services.
We have common repository with classes and libs for logging, filtering, monitoring, testing, etc, but we don't need and use the same services between microservices.
Second tip: use hexagonal architecture with DDD. It is really helpful to have adapters and ports. If you need to change something, it is not problem.
Look at this repository, if you are interested: https://gitlab.com/food-delivery5161742
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With