Search code examples
springmavenmicroservicesdevops

spring boot microservices maven architecture


I am currently building a spring boot application with a micro-service architecture. I am looking for clean ways to reuse code.

My idea is to pull out common code in a shared module. (e.g. base classes which model classes in microservices inherit from, interfaces which are reused in any mvc controller, domain code which is the same for each bound context). Concrete implementations and service-only model classes etc. are on the submodule (microservice) level.

I am building stuff with maven and also managing dependencies. My question is about how to structure maven modules and dependencies in such a setup.

Where do shared libraries go? How and when are they built and referenced via dependency? Is it good to use a BOM for managing dependencies and only override specific versions in microservices when needed? How is the bom included? How and when is it built?

I can think about one way to handle it which I don't really like:

  1. Have a (super-parent) maven pom which handles dependency management and can be included in submodules (micro-services) with import scope. (BOM)

  2. microservices poms build all their dependencies (including BOM and shared module)

Problems:

when declaring submodules for building dependencies the pom must be of type pom aswell, so for every microservice module I would also need a parent pom aswell

If the super-parent or BOM includes a module section which declares all submodules (microservices) I cannot build it from the ms-level, since there would be circular dependencies.

Why would I even declare submodules in the bom? because in some IDEs like Intellij the maven plugin/support includes the submodules in the structure overview.

Can you please point me to some good advice for handling maven architecture for microservices in a solid and clean way? (less code/configuration duplication as possible, performant build etc.)

Thanks


Solution

  • The first thing you should concern about with the microservices architecture is the isolation of the services from each other. That implies that you should share as little as possible.

    As I tried different approaches over past 6-7 years I can confidently say

    • Don't ever use a parent pom for different microservices. Each microservice can use different version of the same libraries depending our their own needs. Having parent pom may sound convenient initially but it creates significant issues in the long run for isolation.

    • Don't ever try to focus on code reuse between the microservices. That doesn't mean that you can't use utility libraries etc. But sharing model classes etc. will bind the microservices to each other which will damage the freedom/isolation substantially. Instead you should rely on proper contract between the microservices.

    I see that your approach are mostly for implementation convenience but there are other things you should concern more over time like deployment/release, maintenance, testing of the components which could be harmed by lack of proper isolation.