I want to be sure what is the best practice for project structure while using microservice architecture.
All microservices can be created as a new maven/gradle project or as a subproject/module.
I think dependency inheritance, project repository should be taken into account.
Due to the nature of the microservices, any service can has a different technology but still most of the services can have same dependencies(e.g. spring-boot)).
Another issue is that should team fetch all services or just a service which will be worked on? so repository structure also will be affected by the structure.
The main reasons to have a multi-module project is to manage dependencies (in the maven sense) between the different modules (and build them together in the right order). Your microservices may call each other, but are not dependent on each other in the Maven sense. So I would not use multi-module projects for them.
Nevertheless, you can define a parent pom for your microservices that defines common configuration and dependencies.
I don't recommend you to have a single project with multiple microservices of different technologies.
If you use Java as a programming language you can have a master project and use it as a parent in your microservices projects. Also, you can have common libraries as dependencies of your microservices projects.
If you want to do a microservices with different technology I recommend you to have a repository for each microservice.
Choosing this option you can deploy and versioning each microservice when you do changes in its code and not when you have changes in another microservice.
Related
Our project team had adopted Client Modules as a way to share DTOs with other Micro-Services (references: https://www.vinsguru.com/microservices-architecture-how-to-share-dto-data-transfer-objects/ and https://www.baeldung.com/java-microservices-share-dto).
However, 1 question that we had in mind was whether to structure the client modules (DTOs) within the Microservice as a multi-module project, or to locate it separately in a different project repo.
In this case, we envision the client-module to be uploaded onto our internal Maven Repository, while the Microservice will be deployed in our Kubernetes clusters.
As such, would like to seek opinion on:
how would you structure your Spring Boot projects if you adopted Client Module to share DTOs and
the pros and cons to structuring the client modules (DTOs) in a multi-module project within the Microservice, or to locate it separately in a different project repo.
Feel free to comment if you have any questions. Thanks in advance! :)
Some of the enterprise projects that I worked on used multi module approaches to separate client and microservice modules. The broad idea is as follows.
Have 3 modules: Client, Integration testing and microservice.
In the client module, place all resources you wish to share with others: DTOs, exception, Feign managers, and enums etc. Package this module as a Jar
Place all service and data layer logic in the micro service modules. This module will be packaged as a boot jar which can be deployed to your targets.
Place integration tests in the integration testing modules. The packaging is optional here.
The pros of this approach is as follows:
There is clear separation of concern between client, service and testing modules.
There is a very tight security: you won't be exposing your service logic unless you would want to.
The cons(Purely my opinion):
Managing the artifacts is cumbersome.
Suppose you have two microservices talking to each other, both share data classes as contracts. While you dont want to duplicate all contracts in every microservices project, whats the best way to share them?
As is see it, there are only two options:
Duplicate shared contracts, while also duplicating code
Compile a first party library and import it
My team had the same scenario some time ago and we decided for a variant of your second point. We used Maven Multi-Module Project, so that one Microservice produced the library, which was then imported by the 2nd Microservice.
Maven Multi-Module Project is explained here:
https://www.baeldung.com/maven-multi-module
It is not a good idea to do project1 > project2 dependency because it might change in the future and you'll end up having to refactor the whole thing.
What I'd do is to create a shared library that's published to an internal Nexus or artifactory, then you can just add this as a dependency to your project so you'll have something like this:
library > project1
library > project2
Another idea to consider is to use something like Protocol Buffers if you are only sharing the data transfer objects. This has the additional advantage of versioning and forward compatibility.
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:
Have a (super-parent) maven pom which handles dependency management and can be included in submodules (micro-services) with import scope. (BOM)
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
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.
I am trying to convert a normal monolithic web application into microservices structure using Spring Boot and Spring Cloud. I am actually trying to create Angular 2 front-end application and calls these my developed microservices in the cloud. And I am already started to break the modules into independent process's structure for microservice architecture.
Here my doubt is that, when designing the flow of control and microservice structure architecture, can I use only one single Spring Boot project using different controller for this entire web application back end process?
Somewhere I found that when I am reading develop all microservices using 2 different Spring Boot project. I am new to Spring and Spring Cloud. Is it possible to create all services in single project by using different modules?
Actually, it doesn't matter to package all those services into ONE project. But in micro-service's opinion, you should separate them into many independent projects. There are several questions you can ask yourself before transforming original architecture.
Is your application critical? Can user be tolerant of downtime while you must re-deploying whole package for updating only one service?
If there is no any dependency between services, why you want to put them together? Isn't it hard to develop or maintain?
Is the usage rate of each service the same? Maybe you can isolate those services and deploy them which are often to be invoked to a strong server.
Try to read this article Adopting Microservices at Netflix: Lessons for Architectural Design to understand the best practices for designing a microservices architecture. And for developing with Spring Cloud, you can also read this post Spring Cloud Netflix to know which components you should use in your architecture.
Currently I am working on microservices too, according my experience we have designed microservices as step below,
Maven
You should create the project with different project. But actually you can separate your project to submodule. So you will be easy to manage your project, the submodule you can use with other project too.
Build the Jar Library put your local repository. it can save your time, you have just find the same component or your functionality then build the jar file put in your local repository , so every project that use this function call point to download this repository, you don't have to write many project same same.
So finally I would like you to create different springboot project, but just create submodule and build local repository.
By creating your modules in different projects you create a more flexible solution.
You could even use different languages and technologies in a service in particular. E.g. one of your services could be NodeJS and the rest Java/Spring.
I am reading spring micro services for next project. Tut said that "The architecture style the main application divided in a set of sub applications called microservices. One large Application divided into multiple collaborating processes.". So already we have a framework maven multi module There I separated the project in my experience. even though it is. why do we need micro services to separate a project?. please differentiate it. thanks in advance..
Every service in the microservice architecture should be isolated which means that the team in charge of that service is able to put continuous deployment in practice without need to deploy other services. In practice, IMHO I think that we can use two approaches using our favourite build tool such as maven or gradle:
Monoproject: domain, repositories, services and controllers are all in the same project.
Multiproject: domain, repositories, services and controllers can be grouped in different modules. i.e domain and repositories are in repository module and services in another module with the same name and controllers in front module.
But, doesn't matter which approach you use the project (mono or multi) should represent one service.