Real Microservices with Java EE
Microservices is one of the most important buzz-words that we have in the software industry today. Not surprising because many big companies, many big projects are using this approach.
But… what about Java EE? Is it possible to build the Microservices, I mean real Microservices, using Java EE? Of course it is and I’m going to show you right now.
Basically this example is working with a scenario where our application has:
1-A Player with rank
2-A Player rank history
Just like a game manager or so. Let's check our application built as a monolith and then break it down into a microservices model.
We have here an example of a monolith built with Java EE. First our Player entity (JPA):
Then the entity for our Player rank history:
Note the relatioship between Player and PlayerRankHistory:
private Player player;
This item will be important when we are breaking down it into microservices.
We also have two beans that will make data manipulation for Player and PlayerRankHistory. They will hold the methods: save, remove, findByID and findAll.
First the PlayerBean:
Then the PlayerRankHistoryBean:
And finally we have the endpoints that will communicate with those beans.
And the PlayerRankService:
Oh, yes… and don't forget to write the tests! We are showing here just the endpoints tests, but the repository has the full tests written (URL in the end of this article).
First the PlayerServiceTest:
Then the PlayerRankHistoryServiceTest:
That's it, we have our monolith ready to be broken down.
First of all, what was before a one single project, now it's split in two.
The Player project has, of course, only the classes related to Player part. And they are pretty much the same as the originals, so we won't show them here, just the project structure bellow:
For the PlayerRank project we have some changes in the classes.
As we said before, there was a relation between the PlayerRank and Player. As we don’t have Player anymore inside this project and each microservice has it’s own database (Database per Service pattern), in this case we are replacing the Player relationship for just Player ID (called just "player").
Now it's up to the application to manage the Player x PlayerRank, as for any other use case of it, like reports, searches, etc. Now this relationship is logical and not physical anymore.
The PlayerRank bean didn't change at all, as same as for the PlayerRank endpoint.
Well, just splitting the project into two pieces isn’t enough. We need something to make the things work together, although they are decoupled from each other.
One approach that we use here is called API Gateway. We just built a gateway to deal with these both microservices.
We built a Player gateway that will hold the communication between your client - it can be a mobile client, a web client, a desktop client… whatever client you have. The gateway will be in the middle of communication between the microservices and your client.
The same approach were used for the PlayerRank gateway:
That way you can keep the contract with your client untouched even if you service is changed (of course, given some limits). You can change the URL, technology, business rules, etc.
Most of the specific activity or management that you need to have for each microservice you can do on its gateway. And if you create another microservice, another application, you can just do the communication with the API through this gateway. Then you have a lot of flexibility to give new features to your clients.
As you saw, it’s quite simple to take your Java EE application and break it down into microservices. Actually, it isn’t just breaking down the whole code, sometimes you'll need to do it also to the environment.
Of course we have many rooms for improvement here, like configuration, service registry and discovery, etc. But this is a handy way for you to get started.
If you want to check the full source code of this example:
Contribute to eldermoraes/javaee8oracledevs development by creating an account on GitHub.
Also check the Youtube video where this example is explained: