Chapter 1 — Introduction to Microservices
Published: 2023-09-27 23:44:37


## Chapter 1 — Introduction to Microservices

![cahpter image](https://cdn-images-1.medium.com/max/2048/1*5eH-mrnxmxnyEwF49UzQzA.jpeg)

### **Introduction**

This chapter gives us an overview of what a microservice is, explains how and when it is recommended to use microservices, and shows us its origins, as well as the difference between monolithic architectures and microservice architecture, the chapter will cover interesting topics like the best practices to work with microservices, a brief introduction to scalability and a little introduction about Domain-Driven Design and how it helps us to build and define our microservices. In this section, will learn all those concepts from a theoretical approach, and to make it more didactic the chapter is going to make use of real-world examples using diagrams, showing technologies, and explaining from a practical approach what the microservices are.

## Structure

In this chapter, we will discuss the following topics:

* Defining a microservice

* History of Microservices

* Key characteristics of microservices

* Benefits and advantages of using microservices in software development

* Challenges related to microservices

* Comparison with other architectural styles

* Monolithic Architecture

* Distributed Monolith Architecture

* Best practices

* Microservices on real-world scenarios

## **Defining a Microservice**

To define what a microservice is, I would like to mention one of the explanations given by ***Martin Fowler***, who was one of the founders of this new concept. Martin Fowler defines microservices as an architectural style that helps us structure an application as a collection of small and independent services that scale and run autonomously. These services communicate through lightweight mechanisms, that is, through the use of HTTP APIs implementing a synchronous connection or through asynchronous communication using message technologies.

It is worth mentioning that the implementation of this architectural style highlights the importance of independence, autonomy, and efficient communication between the different microservices that make up our system, resulting in a microservice that is decoupled from the other microservices, which helps us to develop, test and scale more independently since these processes are implemented when required for each of the microservices without affecting the others.

Figure 1.1 shows some of the microservices used by some e-commerce applications. Figure 1.1, shows the different microservices for this hypothetical case, where the application is split into small services like users, products, shopping cart, and orders, and as was mentioned in the definition each one is independent of the other.

![***Figure 1.1**: Microservices example for an e-commerce application. The Web Application represents one of the possible clients.*](https://cdn-images-1.medium.com/max/3200/0*Nj2dYGlVUrqx3UgG)

## **History of microservices**

A long of this section will present a little bit about the microservice architecture history, In a few paraph, will delve into the intriguing journey of microservices architecture, exploring its historical precedents, origins, influential authors, and the evolution it has undergone to become the powerful and widely adopted approach it is today.

One of the aspects that gave rise to microservices-based architecture were those analyses made of the architectures that preceded it, which were the monolithic and SOA (Service-Oriented Architecture) architectures that were developed in the 2000s. These architectures had significant advantages, such as component reuse and scalability, but also presented challenges in terms of complexity and maintenance. Development teams were having difficulties implementing changes to monolithic applications and dealing with dependencies between different services in SOA. It was here where they began to devise how to improve these processes and how to mitigate the deficiencies that the current and most used architectural styles offered.

The concept of microservices began to take shape in the early 2010s, although its origins lie in the work of some prominent authors. One of the forerunners was Martin Fowler, who in 2014 published an article titled “Microservices: a definition of this new architectural term”, where he introduced the term “microservices” and described its key features. Fowler and other experts such as James Lewis and Sam Newman contributed significantly to the popularization and promotion of this new architecture.

Once the concept of microservices was presented and it began to gain popularity, something happened that would provide a breakthrough for this architectural style. The response from large industries such as Amazon, Netflix, and Twitter, to name a few, quickly adapted this approach as part of addressing scalability and maintainability issues in their applications, increasing the popularity of architecture based on microservices.

This architecture continued to evolve as more companies adopted this approach to developing and maintaining their applications. This caused that as microservices gained more and more popularity, specific tools and technologies were developed to facilitate their implementation and management, such as Docker and Kubernetes, to mention some of the most popular. In addition, the development community began to contribute new patterns and practices to improve the implementation of microservices. Over time, principles and recommendations for designing and managing a microservices architecture were established, focusing on service independence, efficient communication, and fault tolerance.

As in all cases, challenges and debates began to arise about the proper and efficient implementation of the architecture based on microservices. At this point of analysis complexity management, security, and monitoring of microservices became important research and development topics. This caused the development community to start designing solutions to address these issues and improve the overall experience when adopting microservices.

Today, microservices-based architecture is widely adopted in the software development industry, especially in massive-scale enterprise applications and platforms. Its modular approach and its ability to facilitate agile development and continuous delivery have proven beneficial in complex business environments. Although it continues to evolve, the microservices architecture has left a significant mark on the way modern applications are built and managed.

## **Key characteristics of microservices**.

Now that we have learned about what microservices are and have reviewed a bit about their history and origins, it is time to move on to learn the main characteristics of microservices. At this point, we are going to describe each one of them to understand their importance when defining our microservice.

The characteristics we will be addressing help make microservices an attractive architectural style and be one of the best choices for building flexible and change-resistant, highly scalable applications. However, there is still a concern related to these characteristics, which are the challenges associated with each of them. Don’t worry we will address this topic in the upcoming sessions when we talk about “Challenges related to microservices.” That being said, let’s begin.

![***Figure 1.2**: Microservices characteristics*](https://cdn-images-1.medium.com/max/3200/0*CWw7S3HnSWDTEu8B)

### **Independent Components**

This characteristic is based on the autonomy of microservices, as they can be seen as independent components. This helps us to develop, scale, and deploy each microservice without affecting the other microservices that are part of our system. Independence also allows development teams to focus solely on their domains or scopes as a team, without worrying about the other microservices. This results in a smoother workflow and accelerates the product development process.

Another type of independence related to microservices is technological independence, as each microservice can be developed using different technologies and programming languages. This takes into account the needs and specifications of the microservice’s functionality.

Returning to the example mentioned in the definition of microservices, this level of independence can be observed in our hypothetical case of an e-commerce application. In this scenario, each microservice that comprises the system operates independently, focusing solely on its specific functionalities. For instance, we could have a microservice dedicated to user management, another one handling the shopping cart, and yet another responsible for order processing. Each microservice operates within its defined domain, maintaining communication with others as needed.

![***Figure 1.3**: Each request is done to the specific microservice that ensures the domain and functionality independence.*](https://cdn-images-1.medium.com/max/3016/0*ETKu3WDCvdxhGm5v)

### **Granularity**

This characteristic is similar to independence, but it specifically focuses on the tasks and specific functionalities that a microservice will perform. These functionalities are defined with a clear understanding of the domain boundaries to which our microservice will be linked. This approach allows for greater cohesion and improved coupling within each of our services. In the upcoming sections, we will explore how to define these domain boundaries using some of the key features of Domain-Driven Design.

To provide a more precise explanation, let’s consider our e-commerce application, we will focus on two microservices: “Shopping Cart” and “Orders.” While these microservices are related to users and products, each one has specific functionalities that need to be kept independent. However, they can be interconnected through the implementation of microservices communication.

In our example, one of these microservices is responsible for managing all aspects related to the “orders” domain. This includes details such as the involved products, the customer who placed the order, and their basic information, as well as the status of the order. On the other hand, the shopping cart microservice assists in handling the products that customers are interested in, which may later be included in an “order”.

Figure 1.4 shows microservices granularity. Each one defines its functionality scope and its storage based on its functionality.

![***Figure 1.4**: Microservices Granularity representation.*](https://cdn-images-1.medium.com/max/2656/0*spBKtjH1FDPZ1BhP)

### **Decentralized Data Management**

Unlike monolithic applications, microservices architecture recommends the use of an independent database that is managed by each microservice (refer to Figure 1.5). This separation of persistence enables us to select the most suitable persistence system for each microservice based on business rules and usability. The result is a system with a polyglot persistence approach. This approach allows each microservice to utilize different types of databases, such as SQL or NoSQL, depending on their specific requirements.

![***Figure 1.5**: Centralized Storage vs Dedicated Storage*](https://cdn-images-1.medium.com/max/3076/0*A5bJ_n9Lzm9dGiWe)

This separation of persistence management also brings implications for keeping data updated across different storage systems. In monolithic applications, transactions are commonly used to ensure data consistency when dealing with updates between modules. However, using transactions introduces significant temporal coupling. Another approach is the implementation of distributed transactions, which we already know can be challenging to implement.

This is where other aspects are evaluated from the microservices approach. Microservices architectures emphasize coordinating data updates without relying on transactions between services. One proposal suggested by **Martin Fowler** is to avoid using these transactions, with the explicit recognition that consistency may only be eventual consistency. Instead, issues are addressed through compensating operations to mitigate temporal inconsistency.

In our e-commerce example, the process of separating the database becomes clearer as we have a separate database for the customer microservice, another one for orders, and yet another for the shopping cart. These databases can be either SQL or NoSQL, as we discussed in the previous paragraphs.

### **Lightweight communication**

The microservices architecture establishes that communication should be done using lightweight mechanisms, such as standard protocols like HTTP, RPC, or asynchronous messaging. This facilitates the exchange of data between different microservices. These communications are usually achieved through well-defined interfaces, typically using APIs (Application Programming Interfaces), which streamline integration, especially when microservices employ different technologies.

In addition to the implementation of HTTP protocols, there is the approach of messaging through a lightweight message bus. The chosen infrastructure in these cases acts merely as a message router, implementing technologies like RabbitMQ that help maintain a reliable structure in our messaging systems between the message producer and consumer services.

Figure 1.6 shows how the HTTP/RPC communication works between microservices, in that approach is implemented as synchronous communication. The second part of the image is shown asynchronous communication, in that case, the services interact with an intermediary who handles the messages from the producer and will read from the consumer.

![***Figure 1.6**: Synchronous and Asynchronous microservice communication.*](https://cdn-images-1.medium.com/max/2220/0*iP9xQUV8dOSFSbx-)

### **Products not Projects**

At this point, we will discuss cases where development teams exist until the point where a component of our system is delivered, considered complete, and then the development team is dissolved. The component is then handed over to another team that provides maintenance throughout its lifespan.

This is where an approach comes into play, suggesting that a development team should own a software product throughout its entire lifecycle. In this organizational approach, the team takes responsibility for the software in production. Apart from development, the team also handles product maintenance, which facilitates continuous product improvements.

### **Scalability and failure tolerance**

In terms of scalability, the microservices architecture is highly beneficial as each microservice can be deployed and scaled independently based on demand and usage. Scaling a microservice-based application should be easier than a monolith because it just scales the microservice that is needed. Is important to apply the correct scaling techniques based on each microservice. Figure 1.7 Is a representation of how a microservice could be scaled.

![***Figure 1.7**: Scaling a microservice-based application implementing a load balancer.*](https://cdn-images-1.medium.com/max/2828/0*X_Am7eUkvf5dil6f)

Regarding fault tolerance, the microservice approach is also beneficial as a failure in one microservice does not affect the others. As we are aware, a service can fail at any time, so our system needs to detect these failures quickly to either correct them or implement a solution where the service automatically restores itself.

One approach used for fault detection in microservices is real-time monitoring, which allows us to raise alerts when anomalies occur in the behavior or performance of our application, enabling us to identify the source of the issue more rapidly. Don’t worry if we only briefly mentioned monitoring at the moment; we will have a dedicated chapter focusing on these types of solutions.

### **Maintainability and Team Distribution**

In a microservices architecture approach, modularity is an essential aspect that facilitates the incorporation of improvements and the resolution of errors encountered during production. This is where team distribution comes into play, as a team can take ownership of the development and maintenance of a microservice or a set of them. This helps in achieving better progress during software development processes, as having a well-defined domain controlled by a single team makes it easier to detect improvements or errors as well as its solution.

The team distribution approach also relates to the learning curve and domain knowledge of the microservice’s functionality, as the team focuses on understanding and mastering the assigned microservice instead of trying to learn and master the entire application.

Each of these characteristics covers an essential aspect that helps us gain a deeper understanding of this architectural style and its contributions to the software development process. And it shows us how microservices are a popular architectural style due to the characteristics that it offers. We can conclude that the independence, granularity, and lightweight communication enable agile and modular development, facilitating the microservice scalability and adding fault tolerance that is good for our final products. Furthermore, the separation of persistence and team distribution promotes maintainability and continuous software improvement.

## **Benefits and advantages of using microservices in software development**

As we have already seen by studying the characteristics of microservices, it becomes evident that microservices embody numerous best practices that are advantageous for software development. Therefore this section will explore the benefits and advantages that an architecture based on microservices offers. We will consider aspects such as independence, flexibility, and team building, and the benefits they provide for continuous improvement and performance of our applications, such as scalability.

The following list shows the main benefits and advantages offered by the microservices architecture:

* **Independence and Autonomy
**As mentioned previously, each microservice operates independently, allowing development teams to work autonomously and perform updates, maintenance, and deployments without impacting other microservices. This grants increased agility in the development processes, as it permits greater flexibility in implementing changes.

* **Organizational Scalability**
Development teams can be distributed among different microservices, granting them increased autonomy and responsibility for each service. This enhances collaboration between teams and improves efficiency in software development. By enabling teams to concentrate on specific microservices, they can gain expertise and become experts in their respective areas.

* **Technological Flexibility**
Each microservice can employ different technologies and programming languages based on specific needs, providing the freedom to choose the most suitable technology for each service, depending on the domain and the solution it focuses on.

* **Maintainability**
The modularity of microservices simplifies the integration of improvements and error resolution, as each microservice can be maintained and updated independently. This streamlines the maintenance process and allows for greater efficiency in problem-solving.

* **Continuous Deployment**
The microservices architecture enables faster and more frequent deployment of new services or updates, facilitating the continuous delivery of software without causing an impact on other services during deployment.

* **Scalability**
Considering the advantages of independence and modularity, we achieve improved scalability as microservices can be scaled independently based on specific demand. This allows for efficient resource utilization and adaptation to changes in workload and consumption of our microservice, without the need to scale the entire system.

* **Resilience and Fault Tolerance**
This benefit, along with several others, is an essential component of microservices, as we discussed in the previous topic. Based on this, we understand that if one microservice fails, the other services continue to function, thereby increasing the overall system’s fault tolerance. Additionally, with the implementation of a microservices architecture, we can incorporate specific recovery and resilience strategies for each service in the event of a failure.

* **Improved User Experience**
With a microservices architecture, which is closely tied to specific domains, it becomes easier to enhance various aspects of the user experience in a more agile and efficient manner allowing a better adaptation to the users’ needs and requirements.

As can be observed, these advantages highlight that a microservices architecture is an attractive and innovative option for the development of our applications. However, it is important to mention and consider that, just as there are benefits and advantages, there are also challenges that can add complexity to the microservices architecture but don’t worry, these challenges will be discussed in the next topic.

## **Challenges related to microservices**

Now is the time to talk about the challenges, When a microservices architecture is implemented a couple of challenges are present and each one should be tackled correctly by choosing the correct solution to have an exemplary microservices implementation.

The following are some of the challenges presented in a microservices implementation, as well as the recommendation to mitigate the impact related to it.

### **Managing Complexity**

A system based on microservices introduces an additional level of complexity as its functionality is distributed across different services. This increases the complexity of coordinating each service, as well as managing and monitoring multiple microservices, which may require more attention and effort compared to monolithic architectures.

To tackle this challenge, the following recommendations are often suggested:

* **Proper Modularity for the Microservice** 
This involves ensuring that each microservice has a well-defined specific responsibility and is as independent as possible from other microservices.

* **Dependency Management**
This refers to identifying dependencies with other services to establish appropriate communication between them.

* **Monitoring**
 It is advisable to implement monitoring tools for our microservices to help detect potential issues in each of them.

* **Continuous Integration and Continuous Delivery**
Applying techniques of continuous integration and deployment helps reduce the complexity of our microservices.

### **Communication between Services**

Communication between microservices must be carefully designed and managed because microservices operate independently. It is crucial to be meticulous when establishing the type of communication they will have to ensure smooth communication and avoid performance or latency issues.

Some techniques implemented to mitigate this challenge include:

* **Implementing well-defined interfaces**. This point implies defining contracts that will be used for communication between microservices by implementing APIs.

* **Using communication protocols**. As a suggestion we could implement common protocols for communication between microservices, those protocols could be HTTP and RPC, as well as the implementation of technologies that help us to have asynchronous messaging. Those are common techniques at this stage.

* **Fault tolerance**. As you may know, microservices can fail at any time, which can affect communication. Microservices need to implement techniques like retrying requests or auto recoveries to address such failures.

* **Integration testing and monitoring**. These two points are very important as part of our development process, conducting extensive integration testing for microservices ensures smooth communication between services. On the other hand, monitoring helps detect anomalies in microservices communication.

### **Data Consistency and Synchronization**

When dividing an application into microservices, one of the main challenges is to maintain data consistency and synchronization among the microservices. In such cases, it is recommended to implement appropriate strategies that help ensure data integrity and coherence within our system as a whole.

Some of the techniques to address this challenge are as follows:

* **Eventual Consistency**. Instead of aiming for immediate consistency in the data of our microservices, we can prepare them to operate with eventual consistency, where all the data will eventually become consistent in our system.

* **Messaging Patterns and Events**. By implementing events and asynchronous messaging in our microservices, we can ensure efficient propagation of changes throughout our service.

* **Distributed Transactions**. In some cases, it may be necessary to manage transactions from one microservice to another. For these cases, a system is implemented where if a failure is detected the changes in the involved services are rolled back.

* **Domain Boundaries**. As was mentioned before, the microservices need to be focused on a specific domain and handle their data. This helps mitigate consistency and synchronization challenges to some extent.

### **Monitoring and Issue Resolution**

In a system composed of multiple microservices, it is crucial to have the implementation of a monitoring system, which will help us detect problems more easily by managing alerts when an anomaly is detected in any of our microservices. Additionally, monitoring also aids in quickly and efficiently resolving the detected errors.

For systems based on microservices architectures, real-time monitoring and proper logging practices are essential to help us ensure the correct system behavior, the system’s health, and the system’s performance.

### **Security**

Going back a bit to the mention that a system based on microservices is a distributed system, security comes into play since there must be measures to protect the interactions between our microservices, such as requests, and data transfer.

Some of the recommended measures to address this challenge are:

* **Use of authentication and authorization systems in the communication of our microservices**. This point ensures that only the request that contains the authorization used by the system can access our resources that authorization is used to sign the request and allow communication between the microservices.

* **Implementation of audit and registration of events**. Keeping a record of the processes made by each of the microservices is beneficial when detecting anomalies in our system.

* **Protection of data in transit**. In this part of the process, it is recommended to add a layer to encrypt all the sensitive information that is transferred from one microservice to another one. When the communication is done the microservice that is requesting sends the encrypted data, then the microservice that gets the request decrypts it and processes the data.

### **Multiple Microservices Multiple Configurations**

When we have a system based on microservices, each one of them has its specific configuration. In these cases, keeping said configuration updated can be a challenge since a change of credentials or URL can affect cases such as the communication of our microservices.

Some of the recommendations are:

* **Centralized configuration storage**. For these cases, it can be a configuration repository or some configuration management service that allows us to obtain the values quickly and safely.

* **Environment-based configuration**. In our development cycles, our microservices will be deployed in environments such as development, QA, production, etc. To cover all those differences is recommended to have a suitable configuration for each of these environments.

* **Automated deployments and updates**. With the use of automation techniques, configurations could be part of the pipelines of this process, which help us to automatically have the proper configurations for each environment and deployment.

### **Culture and Organization**

When working with microservices, it is good practice for teams to adopt a collaborative mindset, as well as, an organizational structure that promotes autonomy and responsibility for teams and their microservices within their domain.

These are the main challenges that can be encountered when working with microservices. However, as you may have noticed, they can be overcome with proper planning and execution. Additionally, by using tools that aid in the observability of our services, we can easily identify what is lacking in our system to ensure smooth and orchestrated operations.

As a recommendation, understanding and being aware of these challenges before, during, and after starting to build microservices is essential if we want to fully leverage the benefits of microservices architecture and construct robust and scalable systems.

## **Comparison with other architectural styles**

This topic shows a brief comparison between microservices and other architectural styles like Monolithic architecture and distributed Monolith architecture. The comparison will take some of the characteristics reviewed in the previous topics, emphasizing modularity, coupling, scalability, maintainability, etc. in terms of monolithic architecture and a brief comparison between the distributed monolith architecture.

### **Monolithic Architecture**

Let’s start by providing a little description of what “Monolithic Architecture” is. A monolithic architecture could be seen as a traditional way to build our software, where the entire application is built as a single unified unit separated by modules but all part of the same project.

One of the characteristics of monolith architecture is that all its components, modules, functionalities, etc. are tightly coupled and interconnected. That is because this architecture style typically consists of a single codebase, which means that any changes or updates applied to the application are going to require the deployment of the entire monolith due to its nature of being a single unit, which causes the monolithic architecture becomes complex and difficult to maintain as the application grows in size and complexity along its life cycle.

Regardless of the pros and cons related to monolithic architectures, it can still be useful for smaller applications that define simple requirements, we can work with a monolithic application when there aren’t a lot of modules or domains in play and the coupling between the components is low, otherwise, you can opt by using another architecture like microservices that offers a good alternative for big projects that involves multiples domains.

Let me give you an example of a monolithic application. An e-commerce system involves multiple domains like users, products, orders, and shopping carts. In a monolithic application, all those domains are defined as modules that share the same database, and in the case of one module needing to know information related to another module, it can do it by using the functionality defined in the concrete package or accessing the database table. There is where the coupling increases if we don’t carefully apply a good architecture to our code structure.

Figure 1.8 exemplifies an e-commerce application. In that case, there is only one web service, it is split into components that work as a big unit, and all the components point to the same database and share models with each other.

![***Figure 1.8**: Monolithic Architecture representation.*](https://cdn-images-1.medium.com/max/3200/0*EUvrOQxfGc7YtnU7)

**Differences with microservices
**Several key differences between microservices architecture and monolithic architecture that could help us to evaluate the use of microservices in our application, differences are:

* **Coupling**
In contrast to microservices architecture which emphasizes modularity, in a monolithic architecture, all components of the application are highly coupled and work as a single unit. This can make it more difficult at times to apply changes to some specific functionalities due to the change could affect multiple modules.

* **Scalability and Fault Tolerance**
Talking about scalability at the difference of microservices that could be scaled one by one when needed, in a monolithic architecture the scale should be as a single unit, which increases the resources consumed by the application because even if it’s just a module that needs to be scaled, the update is applied for all the application. On the other hand, referring to failures, In contrast with microservices, In a monolith, any failure affects the entire application.

* **Independent Deployment
**In a monolithic architecture, any change or update done to any of the modules causes the entire application to have to be rebuilt and redeployed. In difference with the microservices where the changes in one of them don’t affect the entire application.

* **Maintenance
**In difference with microservices, in a monolith architecture, all functionalities are integrated as a single unit, which means that any changes for some of its components affect the entire system, can cause more complexity for maintenance, and increase the risk of introducing errors in unintended areas that caused by the high coupling. 
If the application is divided into small teams the changes should be coordinated and let the teams know which changes were applied and which modules are affected. This coordination could add more complexity to our development process, in this case, strong communication between the teams to mitigate the impact.

* **Diverse Technologies and Languages
**The technologies and programming language should be standardized along all the monoliths, which means that all the modules in the application will be using the same programming language and the same technologies like database type, Message systems, frameworks, etc.

* **Storage management
**In contrast with the microservices architecture, where each microservice can have its own dedicated data store, and allows each microservice to choose the most appropriate storage solution for its specific needs. In a monolithic architecture, the data storage is handled in a centralized database, and as a result of this centralized solution, is needed to define a common storage type that is shared for all the components defined in the monolithic application. 
Another point to consider when centralized storage is used is the data schemas and relationships between entities are tightly coupled and depend on the overall structure of the application.

* **Granularity**
The granularity in a microservices approach is high, as the components are smaller and can be independently modified, deployed, and scaled to specific needs. On the other hand, the granularity in a monolith is very low, as all components of the application are tightly coupled as a result of the application being grouped as a unit and, in consequence, cannot be independently modified or scaled. Changes in one part of the monolith can impact other areas of the application, and as was mentioned before any change applied in a monolithic architecture causes the entire application should be rebuilt and redeployed as a unit.

With this small analysis, are discovered all the benefits offered by the use of microservices in software development, however, the choice between these two types of architectures is related to the needs and requirements of the application that is going to be developed, that is why it is You must make a detailed and very careful analysis of the needs to make a decision on which architecture is the most appropriate.

For smaller scale and simpler applications, the monolithic architecture may be suitable due to its simplicity and lower management complexity. However, for more complex and growing applications, the microservices architecture offers greater flexibility, scalability, and adaptability to meet changing business demands.

### **Distributed Monolith Architecture**

The distributed monolith sometimes pretends to be a microservice architecture but there are key differences that can help to detect when our application is a distributed monolith.

This architecture style split the monolith into small services to try to reduce some of the challenges related to monolith architecture, but at the difference of microservices, this kind of separation is still tightly coupled because it still uses the same storage management, sometimes shares some of its codebases as a library, and the most of the cases all its interactions between its services are done of a synchronous way, that results on the need of update all the services that are related when a change or update is applied in some of the components.

In a microservice architecture, the definition of clear boundaries based on the well-defined domain responsibilities for each one of the services is of vital importance and is one of its main principles. In a distributed monolith these boundaries aren’t well defined at all and it causes more dependency between each one of the services increasing the communication to share data.

In difference with the microservice architecture, the distributed monoliths use to share data models between services, then if any change is applied to one service, it can impact other services that use the same model, leading to tight coupling and reduced maintainability.

In a distributed monolith, the tight coupling between services can make it harder to change or refactor individual services, reducing the team’s agility and overall development speed.

Independence and Fault Tolerance are other characteristics that are affected in a distributed monolithic architecture, in contrast with the microservices, the distributed architecture is less fault-tolerant, caused by the coupling of multiple services, in this case, if one of the services has an error all the services related to that functionality will fail.

When a design for a new application is started, all those aspects mentioned above have to be taken into account and try to solve them by implementing the characteristics of microservices, this helps to reduce the complexity and the erroneous implementation of the architecture based on microservices.

## **Best practices**

In this section, we will explore the key best practices for designing a robust architecture based on microservices, crucial for achieving excellence and maintaining high-quality applications.

It is worth noting that many of these best practices are deeply rooted in the core characteristics of microservices. As this section delves into each practice, you’ll discover how they align with the fundamental principles of microservices architecture, enabling the harness of its full potential.

*“Note: Several best practice concepts have been previously covered in the preceding sections. In such cases, we will present a concise summary of those points to avoid redundancy and maintain focus on new insights and implementation strategies”.*

* Define domains for each microservice

* Communication via well-defined interfaces

* service decoupling

* Independent scalability

* Fault tolerance

* version management

* monitoring and recording

* Automation and CI/CD

* Security

* clear documentation

* Integration testing

* collaborative development

* continuous reassessment

**Microservices on real-world scenarios
**In this section, we will explore how some of the world’s leading industries, including Netflix, Uber, Airbnb, Amazon, and Twitter, have embraced microservices to power their platforms. We’ll delve into the fundamental principles of their microservice architectures and how they leverage this approach to achieve impressive scalability and flexibility.

### **Netflix**

Netflix is one of the most popular streaming applications that uses a microservices-based architecture. Each key functionality of the platform, such as content search, video playback, movie and series recommendation, and user profile management, is implemented as independent microservices. This allows each team to focus on developing and maintaining a specific service, which streamlines the development process and makes it easier to adopt new technologies. Additionally, Netflix’s microservices architecture allows it to quickly scale to handle large numbers of users and transactions around the world.

### **Uber**

Uber, the popular ride-sharing app, uses microservices to manage the various features of its platform. Microservices handle user authentication, real-time geolocation, driver assignment, payment processing, and user notifications. Each microservice can independently scale on demand, ensuring that the application can handle thousands of concurrent requests in different locations.

### **Airbnb**

Airbnb, the peer-to-peer accommodation rental site, has adopted a microservices architecture to manage its global platform. Accommodation search and booking services, user and payment management, and review and rating processing are some examples of microservices that work independently. This modular architecture allows Airbnb to quickly introduce new features and scale its services around the world.

### **Amazon**

Amazon, the leader in e-commerce, uses microservices to power its wide range of functions. All aspects of the platform, such as product search and filtering, shopping cart, checkout, and inventory management, are implemented as separate microservices. This architecture allows Amazon to scale efficiently during peak demand seasons and ensure optimal uptime at all times.

### **Twitter**

Twitter is a social networking platform that uses microservices to manage millions of tweets and user requests in real-time. Its services include user timelines, mentions, notifications, searches, and trends. Twitter’s microservices enable fast data retrieval and a real-time experience for its millions of users around the world.

## **Conclusion**

In this introductory chapter, we embark on a journey to explore the fundamental principles of microservice architecture. we have covered all the essential aspects to understand and appreciate the relevance of this architecture, we have covered from the basics to the practical details, revealing how microservices have transformed the way we build web services.

The important points to remember are the following:

* Microservices-based architecture aims to decompose monolithic applications into small, independent components, each with a clearly defined functionality.

* In studying the key characteristics of microservices, we have observed their emphasis on high cohesion and loose coupling.

* Microservices provide excellent scalability and ease of maintenance, making them fundamental attributes for implementation in modern and highly dynamic environments.

* Remember the countless advantages and benefits that microservices bring to software development, including greater agility in development, continuous deployment, improved scalability, and the flexibility to utilize different technologies for each microservice, among others.

* When considering the adoption of a microservices architecture, it is crucial to take into account the challenges and difficulties that we have already analyzed.

* We have presented a comprehensive guide on determining the right time to implement microservices. Additionally, we have emphasized best practices to ensure the effective development of microservices.

Microservices represent an outstanding solution for software development. With their capacity to address present and future challenges, microservices have evolved into an indispensable tool for driving innovation and achieving success in software development.


--------------

Next reading:
Chapter 2. https://dev.to/josueparra2892/chapter-2-introduction-to-microservices-part-2-479l