Best Practices for Microservices Architecture

Nisal Pubudu
Geek Culture
Published in
5 min readJun 8, 2021
Photo by Leon on Unsplash

In my previous article: Introduction to Microservices, I have discussed about Microservice Architecture, its characteristics, and its advantages/ disadvantages. If you are new to microservices, I highly recommend you to go through that article, unless you are comfortable with basic microservices knowledge. So, in this article I’m going to discuss about best practices that you should know to build successful microservices application.

Domain Driven Design

When you have to develop a Microservices application, the very first challenge you have to face is, to split a large, complex application into small, autonomous, independently deployable services. If it is not split in proper way, it will be not a loosely coupled Microservices. As a result, it will have all the disadvantages of a Monolith architecture. Fortunately, there is a good solution called Domain Driven Design. This helps your software team and architects to understand the different business domains, so they can design microservices based on those business domains. Therefore, it is important to have a fresh Domain Driven Design, before developing a Microservices application.

Prevent Hardcoded Values

In microservices architecture, there is a disadvantage, that it has all the associated complexities of the distributed system. So, assume in your microservices application, there are 2 services named as “A” and “B”. In case, if service “A” wants to call service “B”, A should have B’s address. The address might be a host name, URL, or an IP address. But the thing is, some developers used to hardcode this address. There is nothing wrong in that, until your network team decide to change the address. As a result, developer need to change that hardcoded address in service “A” and deploy it again. So, in microservices application, the code should be always dynamic. In this scenario you can use a service discovery tool to discover the other service.

Logging

Logging is something that you must do, whether you develop a monolithic or microservices application. But the problem is, when it comes to microservices, we spend a lot of time thinking about the business boundaries and the best way to split our application logic and we forget to think about the logs. So, lack of logs is not a good practice, and same goes if you have unnecessary logs than required.

Correlation ID

Usually in microservices, finding issues and logging them is a bit more complicated than monolithic, because it has multiple services. For example, let’s say there are 3 services named as “A”, “B”, and “C”. Now you’re logging access and error logs for each service. Assume if you find an error in Service B, it might be useful for you to know whether the error was caused by the request coming from Service A or the request sent to Service C. So now you have to know all the requests in the services that are related to. However, if you have a correlation request ID, then you only need to look for that ID in the logs. And you will get all logs from services that were part of the main request to the system. Moreover, you can know which service the main request spends the most time in, and if a service is calling other services more than once.

So, the point is don’t log everywhere, log only where you initiate the process. However, make sure to log a stack trace to understand where the issue actually happened, otherwise you will get confused and have a hard time while searching where the issue occurred.

Versioning Microservices

Whether you develop a Microservices or Monolith application, there are two standard versioning techniques, which are popular among the software community: Semantic versioning and Calendar versioning. However, when it comes to microservices architecture, versioning is very useful since developers need to target individual services for updates rather than whole applications.

1) Semantic Versioning

Semantic versioning is a technique, that uses three non-negative integer values to identify the version types. In this technique the version format represent as “MAJOR.MINOR.PATCH.”

Semantic versioning is an ideal practice when you are working on a project with many modules (services) and each module is interdependent on another module. As a result, Semantic versioning is considered as the most suitable versioning technique for microservices.

2) Calendar Versioning

Calendar versioning is bit similar to the previous discussed technique, the Semantic versioning. However, this approach uses calendar dates instead of non-negative integers. In calendar versioning, it doesn’t strictly require a particular date format, but it must clearly indicate the year, month and day.

Calendar versioning is considered as a good practice when applications operate on regularly scheduled updates, since it helps developers to find previous or existing versions simply by searching for the release date.

If you want to know more details about microservices versioning techniques, you can follow this link => https://searchapparchitecture.techtarget.com/tip/Get-to-know-4-microservices-versioning-techniques

Handling Authentication and Authorization

When you are implementing these mechanisms within your microservices application, you have to make sure that you follow Global Authentication & Authorization strategy. In this strategy, there is a dedicated microservice that handle authentication and authorization process. Therefore, each business service must authenticate the request before processing it by downstreaming it to the authentication service.

Managing Dependencies

In microservices architecture, managing dependencies is different than monolithic application since, each service operating on its own. However, a service may need access to another service. As an example, assume there are 2 services named as “A” and “B”. So, when you want to deploy A, if it required to deploy B service too, means you violate the microservices architecture. Therefore, make sure to manage dependencies carefully.

Fault Tolerance

When you are developing a microservices application, there are high possibilities to have more failures. Therefore, you need to properly manage those. Mostly, if your microservice is dependent on another system to provide a response, and if it takes more time to respond, it will affect your applications overall performance. Fortunately, we can avoid this by using a circuit breaker to timeout the external call and returning a default response or an error. This will keep out failing services and as a result, that microservice will work without any failure.

Documentations

Even though, most of the developers don’t like to hear this word, documentation is an essential part in any software development. Therefore, you need to document your work properly, otherwise another person will not get a clear idea about the services. However, there is a tool called as Swagger, which will help you to generate documentations in real time. So, you can write documents in technical terms and Swagger will convert them into proper and attractive documentations.

--

--