In this article I want to explain how you can migrate from monolith into microservices architecture using different cloud computing environments, what kind of shared libraries you will probably need to create and what are common archetypes for rapid development cycle.
Monolith to microservices in three “simple” steps

Step #1
First step is to convince all developers and managers that your current application is no longer sustainable. This is a very tough task and it requires to fully understand migration process from ugly dinosaur to microservices.
Your application probably consists from several maven modules divided as follows:
- model
- dao
- service
- app
Model
Module contains DTO objects and entities. Maybe you put here persistence.xml with JPA configuration and simple unit tests for testing of some logic of your POJO objects.
Dao
Dao module consists of several DAO classes which are used for loading, storing, deleting of your entities into database.
Service
The core of the application itself. You can find anything you want – business logic, integration to external services, forgotten DTOs, classes which obviously belongs to ice age and so on. If you get lucky, you maybe find some unit and integration tests – but do not get too excited.
App
This can be anything – from web service endpoint, frontend portal packed service module into ear and so on. Oh, and did I mention that all pom.xml files looks like total mess?
If you identify your application as described above and you successfully convinced managers and developers that there is time for CHANGE, follow Step #2.
Step #2
In second step you will need to separate your application into several projects. You will have a lot of duplications, but it is ok – you will remove most of duplicated code in next step. For simplicity, keep your database tables as they were designed in your monolith. The only change you need to do with your database is to remove foreign keys for tables which belongs to different microservices. Remember that in final step these tables will not be able to access to each other, because they will be separated in standalone sandbox (each microservice should have it’s own database).
Step #3
Final steps consists from several improvements:
- super pom – I strongly recommend to create maven super pom project which contains common libraries and plugins definitions, profiles and so on. You can have multiple levels of super pom – one used to frontend based applications, another for rest like apps.
- shared libraries – put here all shared logic, models, exceptions, services. It does not have to be one project. You can have multiple libraries for different purpose – for instance, for our startup www.turnonline.biz we have created several open source libraries separated by purpose – one for common wicket components, another for GWT, common services and so on. You can find all of our open source projects here.
- client factory – this is actually one of your shared library but I want to point out that for several of my projects I have created this one purpose library which is used to create facade for several web service or rest integrations. It consists from pre-generated clients (generated by apache cxf codegen maven plugin, but you can use any maven plugin), so you generate clients only once and use them for every microservice which needs them.
- libraries bom – this is used as a base line of your libraries version – in maven perspective it is actually an composition of dependencies opposite to parent pom’s.
- full database separation – the hardest improvement step. You need to separate your tables into separated databases – one microservice = one database. There will be probably a requirement to keep data synchronisation between monolith and microservices.
Microservices comparison in different cloud computing environments
Infrastructure as a service (IaaS)
You should deploy microservices to IaaS only if you really need to. There is too much configuration overhead (network, ram, disk, vm) with only one benefit you would hear mostly from system admins – you have everything under control. In microservices/cloud environment you should get rid of all configuration mumbo jumbo and focus only what is really important – how fast you can transfer business requirements into production.
Another problem with IaaS microservices is that starting of VM can take several minutes.
Use IaaS only if you really need to. There are better abstractions build on top of IaaS environment.
IaaS java providers:
- https://cloud.google.com/compute – Google compute engine
- https://aws.amazon.com/ec2 -Amazon Elastic Compute Cloud
Container as a service (CaaS)
Far better approach than IaaS. It is not perfect because you need to configure additional components like service discovery, identity provider, api gateway, load balancer, high availability, deal with service versioning and so on. There are ready made solutions to solve these problems like Docker swarm or Kubernetes but you need to install and configure them which is not perfect for developers.
Starting of CaaS microservice is faster than IaaS but not so fast as with serverless engines.
CaaS java providers:
- https://cloud.google.com/containers – Google containers
- https://aws.amazon.com/ecs -Amazon Elastic Containers Service
PaaS
With PaaS you do not have to worry about load balancing, scaling, versioning – environment handles it automatically. PaaS, also referred as serverless, is built on containers with additional features and services. For instance there is list of services and features for Google App Engine:
- logs (stackdriver) – monitoring of all logs divided by service/version/instance
- mail – email api
- search api – full text search api
- blobstore – api for storing big data objects like documents, video
- memcache – cache api – available in shared or dedicated modes
- datastore – NoSql document based database
- task queues – asynchronous processing (job can take maximum 10 minutes)
- image service – used for runtime image resizing and a lot of other useful features
- error reporting – define which errors you want to accept and engine sends email notifications. You can also download mobile app which will notify you if some error occurs
- cloud endpoints – custom implementation based on Open API Specification. Main advantages are possibility to generate java client, built in support for authentication/authorization/quota checking and monitoring of your endpoint.
- monitoring – every api including your microservices are monitored and you can see real time statistics
PaaS java providers:
- https://cloud.google.com/appengine – Google App Engine
- https://aws.amazon.com/elasticbeanstalk -Amazon Elastic Beanstalk
FaaS
Another serverless environment most suitable for event driven microservices. Typical use case are calculate discount for product, resize images after upload, notifications and so on. Advantage of FaaS is how fast they can serve microservice content (several seconds – compare it to IaaS where you have to wait several minutes) and automatic scaling.
FaaS java providers:
- https://cloud.google.com/functions – Google Functions – currently supports only javascript language
- https://aws.amazon.com/lambda – AWS Lambda
Rapid microservice development
In your project you will probably end with several microservices (probably tens or more). I strongly recommend to keep the structure and coding rules for all of your projects the same. The reason is simple – if every project will have it’s own rules, you will end up with total mess – something totally unacceptable in microservices. Here are some simple rules I used for my projects:
Project structure
- {project}-impl – contains business logic, entities, unit and integration tests
- {project}-rest-endpoint – wrapper around impl module. It is responsible for input validation, mapping of DTO objects to entities and calling of business logic
- {project}-rest-client – contains rest client. In enterprise based projects I used resteasy library provided JBoss. If you are planning to use cloud, I recommend to use google endpoints which will generate java client for you.
Package structure
- com.pojo.blog.model – entities and DTO classes
- com.pojo.blog.service – implementation – for instance BlogService, BlogServiceBean
- com.pojo.blog.exception – definition of possible exceptions – prefer RuntimeExceptions
- com.pojo.blog.rest – package for either endpoint (BlogEndpoint) or client definition (BlogClient)
- com.pojo.blog.mapper – configuration and definition of custom mappers (for example orika mapper)
- com.pojo.blog.config – I put here Spring or Guice configuration
Testing
In your project you should have at least two types of test – unit tests and integration tests.
Unit tests should test only one class and you should mock all of its dependencies. To mock dependencies you should use some mocking library:
- mockito – very simple and easy to use mocking framework. It has support to setup and verify expected outputs of your service calls. If you have never used mocking in your project, you should use mockito as a starting point
- jmockit – advanced mocking framework – use this only when you have some experience with mocking and need to use advanced features including writing of custom expectations and verifications, static methods mocking and so on.
Integration tests are used to test external resource (for example database). I usually suffix integration tests with *IT and create maven profile to exclude integration tests from regular build. Integration tests are resource eaters so I run them only once per day – usually in nightly builds.
Archetypes, or do not reinvent the wheel
Depending on where you plan to deploy microservices there is a list of archetypes you can consider to use:
- appengine archetype – useful if you want to implement your microservice in Google App engine
- spring boot – useful for AWS cloud based microservices.
- turnonline cloud endpoints – microservice based on the Google Cloud Endpoints Frameworks (REST) designed for Google App Engine Java 1.8 standard environment.
- turnonline frontend – microservice for frontend applications – it has build in implementation of IAM, account management and much more.
Conclusion
Implementation of microservices consists from three steps: convincing everybody that it is time for change, separate monolith into microservices, incremental continuous enhancement of microservices.
Avoid using of IaaS as a environment for microservices, start at least with CaaS, however most recommended way if you want to take full advantage from cloud is to go serverless (PaaS, FaaS).
Apply same rules for every project, use existing or create your own shared libraries and use archetypes for easier development.
Sources:
why we should separate monolith into microservices?
LikeLike
To simplify things for development team, microservices are better managabale and scalable. Also microservices should be implemented as new features not new projects which improves time to market, which can save the money for the company.
LikeLike