During the past few years, designing applications as a collection of Microservices are becoming a common architectural pattern. It is important to understand Microservices is not a silver bullet and meant to solve all the software problems out there. However, there are many success stories out there of adopting Microservices by many big players in the software industry which fuels the uprising trend.
Similarly, there are many failure stories as well and the numbers could be even higher since many of them doesn’t go out to the public. One of the main reasons I have seen for failures is the lack of understanding what we are dealing with when designing Microservice architectures.
One of the important lessons I learned designing Microservices is that it demands a deep understanding of distributed systems and without this knowledge, it is likely to end up in doing the wrong abstractions and communication between Microservices.
I have seen many occurrences where developers claim to say that they have adopted Microservices architectural style but when going into the details it is not the case. Let us look at few common mistakes people do when designing Microservices.
When designing Microservices, there are several key points, I validate over and over again in the design phase.
On the other hand, trying to do a big design upfront dividing the Business Domain for a large number of Microservices is not practical either. It is always challenging to find the golden number of Microservices to start with but its better to start small and divide later.
You can also consider areas such as Security, Privacy of Data (Especially with GDPR requirements), Domain Driven Design Practices and most importantly the composition of the development teams and sub-teams to fuel your thoughts.
One of the clear benefits I have seen with Microservices is that, although the overall architecture is complex considering overall services and interactions which requires expert design skills, implementing individual services becomes simpler with their own lifecycle, improving developer productivity in long-term.
If you are designing Microservices in Cloud, Serverless technologies and managed services could potentially solve most of the challenges without needing to write code or use third-party middleware. For instance, I’m often using AWS SNS with Lambda (governed by SNS policies for message format contract) as the pub-sub messaging solution to synchronize data between the databases in Microservices. For Microservices that needs to be deployed in an on-premise data center, there is Open Source messaging middleware like Apache Kafka which could potentially replace AWS SNS.
Using Identity Server (e.g; Amazon Cognito UserPools) for Authentication and Authentication Federation could be also a good choice to integrate rather implementing it as a Microservice from scratch. It is also useful to use stateless tokens like JWT for both for authentication and authorization (using claims), which could be validated by different Microservices without explicit dependencies.
I have been often using OpenID Connect in multiple projects to implement authentication across Microservices (using the standard authorization flow with OAuth2.0) which proved to be much convenient in the long run.
In a Microservices implementation, you can consider each of the services as an individual project and organize the code artifacts and CI/CD setup around each service. However, it is also important to identify the common interaction channels between services (e.g; RestAPIs, Pub-sub topics, Queues & etc.) and treat them separately having their own change management process. This plays a crucial role in making sure the services interact with each other without causing a change in interfaces to break the applications.