Lagom by default creates two modules for every microservice - API and implementation.
Is it possible to divide one microservices into 3+ modules?
Absolutely. You would do this the same way you would with any other Java or Scala project: create a sub-project that is an internal library included into your service.
For an example of this look at the Online Auction Java example Lagom project. Specifically, the security and tools sub-projects. These are included into other services using the sbt dependsOn method in build.sbt.
For example:
lazy val itemApi = (project in file("item-api"))
.settings(commonSettings: _*)
.settings(
version := "1.0-SNAPSHOT",
libraryDependencies ++= Seq(
lagomJavadslApi,
lombok
)
)
.dependsOn(security, tools)
In this case, it is the API project that depends on the additional libraries, but you could do the same thing with your implementation project to use libraries that are not needed by the API. Note that the implementation project also depends on its corresponding API, so any dependencies of the API are inherited by the implementation.
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.
I have a library project that consists of two different APIs (a and b) which should operate on the same core and base code. core is hidden from the user of a or b so there is an implementation dependency to core. But base is exposed to the user of a or b so there is an api dependency to base.
This is all fine as long as you stay in the Gradle world. But it becomes more complicated when you're publishing a and b with the maven-publish Gradle plugin. It creates an artifact of each of the modules separately and (correctly) outlines dependencies between them. But I don't want to expose core and base separately. Instead, I'd like to bundle them into one artifact for a and b each, where types in core stay internal and those in base are exposed.
Is there a way to do this with maven-publish?
You'll want to create a fat/uber JAR. There are plenty of tutorials out there, but a common approach is to use the Shadow plugin: https://imperceptiblethoughts.com/shadow/
You would configure the Shadow plugin to have core and base to be embedded/included in a and b without having to publish them.
There are 4 projects
a (api) - depends on base, core
b (api) - depends on base, core
core (lib) - depends on base
base (api) - none
assuming that all are building with java-library plugin.
If I got your question right - you want the end-users to see api's -a, b, base but not core - I am assuming this is applicable for DEV / Compile-time;
if above is correct - this is not with maven-publish; but rather dependency declaration
please see https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation
in a and b build.gradle
api base
implementation core
in core build.gradle
api base
we have a kotlin-microservice that needs to expose a maven-artifact that defines all DataTransferObjects that are required/emitted by that microservice (e.g. kotlin data-classes that represent events published to the event-bus).
client of that microservice is however a pure java application which shall depend on this kotlin-DTO-maven-artifact but not transitively get the kotlin-stdlib or any other kotlin-specific dependencies injected.
can we provide the kotlin-DTOs without introducing any kotlin-dependency?
The easiest and the most reasonable for me would be to create those DTOs as Java classes since the Kotlin is compatible with such classes
You don't need for this any additional tools or tricks. Inside this artifact you can easily use Lombok to not write plenty of boiler plate code
I want to use a JWT library in Lagom but I'm not certain what library to use. I use Lagom with the Java api.
I found:
Java libraries, but they are all exposed through gradle
Scala libraries, but I'm not sure how to use them when I make use of the Java api in Lagom.
Any help?
I guess that using Maven would be the most obvious solution since Lagom supports it now.
Alternatively I'd guess there would be a way to integrate a scala plugin, build with sbt and link the Java code after compilation.
I also encountered this problem, and after a long search and long time spent in this problem, I decided to implement my own mechanism while relying on the oAuth2 standard. I understood the mechanism of oAuth2 and I made my own authentication module. It is not difficult to implement
My previous answer was wrong.
There are two better options:
1) Add the library jar manually as unmanaged dependency in the lib folder
2) https://alvinalexander.com/scala/how-use-maven-repository-library-with-scala-sbt
Quoted:
In your build.sbt:
libraryDependencies += groupID % artifactID % revision
For example:
<dependency>
<groupId>net.sourceforge.htmlcleaner</groupId>
<artifactId>htmlcleaner</artifactId>
<version>2.2</version>
</dependency>
Becomes:
libraryDependencies += "net.sourceforge.htmlcleaner" % "htmlcleaner" % "2.2"
As mentioned in other recipes, because SBT and Maven both use Apache Ivy under > the covers, and SBT also uses the standard Maven2 repository as a default
resolver, SBT users can easily use Java libraries that are packaged for Maven.
Glad that I will be able to use sbt after all! :-)
I was going to couple of blogs to get the basics of maven, in the mean time I was confused when I can use the multi module project. It will be great if the answer includes example.
The main idea is that you have small modules that are dependent on each other and can be grouped together. Its not necessary that all sub-modules in a multi-module project be dependent on every other sub-module.
Lets consider you have multiple modules for an application (e.g a social networking application) that belong together. These modules can range from smaller modules like a client consumer module or a server module that will serve requests initiated by the client module, an ejb module that will hold your beans that are used by both the server and the client module and a deploy-able web module that would comprise of your front-end application etc.
This is usually handled via a multi-module build which means all modules have the same version number, are bound together under a similar platform (a social networking application in our example) but can be accessed and used by other separately.
Please check How to assemble multimodule maven project into one WAR? to know how to package a multi module project in a war file. also, you can check maven official site on Introduction to pom file