A Friendly Introduction to Microservices
Tags: microservices
Published: 2023-07-02 23:23:56

## Disclaimer

_This article is a compilation of things I've learned while using microservices architecture in my current job. A lot of this content came from notes I've taken during the process of searching videos, blog posts and books. If you recognize something that you wrote or created feel free to hit me up so I can give the credits. Also, if something in this posts are inaccurate or outdated, please comment and discuss it with us! We're all here to learn and get better :)_

## What are Microservices?

Microservices is an _architectural approach_ where applications are divided into a **collection of small independent services** that are modeled around a business domain and communicate over well-defined APIs. A service encapsulates functionality and makes it available to other via networks.

So why is it so trending? What are the benefits? To better understand this, let's talk a bit about monoliths. Monolithic applications are constituted of complex tightly coupled process that run as a unique service. If one function of this application experiences a peak of usage, we need to scale the entire system to deal with this demand. Also, if we need to fix a bug in one single functionality, it is necessary to shut down or redeploy the whole application.

On the other hand, with **microservices architectures we have separate independent components** that run domain specific services. **Each service can be developed, deployed and scaled independently.**

![Source: AWS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3gd49fnuo52xfy63wapi.png)

Taking as an example the case presented above, instead of having one single application dealing with all kinds of business logic (users, threads and posts), in a microservices architecture we'd have **one single service** for each of these. That separation of concerns allows for better code understanding, faster deployability and team coordination. For example, if a new post feature needs to be added, there is no need for the users' and the threads' teams to get involved, and only part of the application needs to be redeployed. **All logic about this specific business domain is encapsulated.**

## Main Characteristics


![Source: freecodecamp](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/arso7n0xqhu8rm09b9qq.png)

The picture above portraits well one of the most common mistakes when we talk about microservices. **Building a small monolith does not make it a microservice.** The goal of this architecture is not building lots of small services, it is about splitting a complex service into multiple smaller (not necessarily small) services that follow some design principles we will discuss soon.

So what makes a service a microservice? There is no rule of thumb to define an architectural style for microservices, so we'll discuss its most common and relevant characteristics.

### Highly Specialized

Each service on a microservice architecture should have only one purpose, a functionality to serve, and do it effectively.

### Independent Deployability

Independent deployability is the idea that we can make changes to a microservice and deploy it to the end users without having to touch any other service. This makes it easier to update code and reduces the time to release new functionality.

### Domain-Driven Design

Is a way to define the service boundaries in compass with the real-world domain the software is inserted. Each service is designed to solve a domain-specific problem and should be fine grained. If it starts to grow too much it could be necessary to break it into smaller services.

### Flexible Scaling

A microservice can be independently scaled to meet demand for the functionality it supports. This provides huge cost savings and increases system availability.

### Loose Coupling

Microservices are independent and loosely coupled. They often communicate via messages or HTTP requests and know little about each other. Usually, a change to one service should not require a change to others.

### Technological Freedom

Because services are decoupled and deployed separately, there is no need for them all to be developed using a single technology. Microservices allows teams to choose the best stack to match the problem they're trying to solve without affecting other teams.

> _If an application is decomposed into multiple services, you can expect many single service changes to only require that service to be redeployed. That's not absolute, some changes will change service interfaces resulting in some coordination, but the aim of a good microservice architecture is to minimize these through cohesive service boundaries._

## How to Define Good Service Boundaries

There are three concepts that are vital to address when it comes to defining microservices boundaries. We'll discuss them bellow.

![Source: Medium](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5wu7uykd9xasrx7s57qf.png)

### Information Hiding

Information hiding is all about **hiding as many details as possible** behind a service boundary. To others, it may act like a black box. Some benefits of this idea are:
- More **work can be done in parallel** since services can be developed independently and don't rely directly on information from other services.
- Each service can be **looked and understood by itself** making it easier to manage the whole system.
- Services can be modified and **released independently** allowing changes to be done to specific ones.

The connections between services are basically assumptions one makes about the other. By keeping this assumptions small numbered it becomes easier to change one service without impacting the other.

### Cohesion

Since one of our goals when adopting microservices architecture is to increase speed when making changes in business functionality, it is important to **group functionality** in such a way that we can make changes in as few places as possible. In other words, we want all related logic to stay on the same place.

If related functionality is divided across multiple services that means the cohesion is weak. Our goal when defining our service boundaries is to **maximize cohesion**. We want each service to encapsulate all related behavior and data together.

### Coupling

When services are **loosely coupled**, a change made to one service does not impact on another one. Hence, our goal is to minimize coupling so we can deal with services separately, enabling them to be managed by different teams.

To achieve all the benefits from adopting microservices architecture, it is important to follow strictly these three design principles.

## Microservices Communication

In monolithic applications, communication is usually called **intra-process** because it is done internally, via method calls. For example, we could have two classes invoking each other's methods in order to execute their own functionalities. This is probably the simplest approach, but keeps functionality inside the application **extremely coupled**.

With microservices, since our functionality is spread across multiple distributed services, the communication happens throughout the network and is called **inter-process**. Let's try to understand and classify the different styles of communication.

![Source: Building Microservices](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sm8yh3kpzvwbtcfrjjse.png)

### Synchronous vs Asynchronous

In a synchronous blocking call, a microservice sends a request to another process and **blocks its own execution until the request is completed** and/or a response is received. This approach is very familiar to most programmers because we usually learn to program in a synchronous way, but it brings with it some issues such as the inherent **temporal coupling** between the services, that often results in time delays.

> _Synchronous calls start to become problematic when you start to have chains of blocking calls_

## Conclusion

Microservice architectures are definitely something to have in mind when developing complex applications and will be trending for a while. Although we've discussed a lot of great things we can achieve with it, there are some difficulties we should be aware of. Monitoring and troubleshooting is something quite hard in microservices applications, it is difficult to understand the impact of one single service going down on the rest of the system, for example. Testing is also a bit overwhelming since we sometimes need to test across multiple processes.

The best approach is to analyze the problem, context, technologies skills, understand what is your goal and decide if microservices is the best way to go. Microservices is a architecture not the one.