<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Israel Parra</title>
    <description>The latest articles on DEV Community by Israel Parra (@josueparra2892).</description>
    <link>https://dev.to/josueparra2892</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F890942%2Fe68e0d91-aa2e-4de7-a4b9-9ddb6338d161.jpeg</url>
      <title>DEV Community: Israel Parra</title>
      <link>https://dev.to/josueparra2892</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/josueparra2892"/>
    <language>en</language>
    <item>
      <title>Chapter 5 - Understanding HTTP Protocols and REST APIs</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Thu, 28 Sep 2023 00:00:15 +0000</pubDate>
      <link>https://dev.to/josueparra2892/chapter-5-understanding-http-protocols-and-rest-apis-302p</link>
      <guid>https://dev.to/josueparra2892/chapter-5-understanding-http-protocols-and-rest-apis-302p</guid>
      <description>&lt;h2&gt;
  
  
  Chapter 5 - Understanding HTTP Protocols and REST APIs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Building our first webservice with Go (Part 2)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2AjS9JMUs3EjqDLS8pCFcIUw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2AjS9JMUs3EjqDLS8pCFcIUw.jpeg" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following list is the previous chapters of this series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-1-introduction-to-microservices-5a2c"&gt;Chapter 1 — Introduction to Microservices&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-2-introduction-to-microservices-part-2-479l"&gt;Chapter 2 — Introduction to Microservices (Part 2)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-3-domain-driven-design-and-microservices-371b"&gt;Chapter-3 Domain-driven design and microservices&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-4-advantages-of-using-go-for-web-development-4b0k"&gt;Chapter -4 Advantages of using Go for web development&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I recommend you take a look at the previous chapters if you have not read them yet. That will help you to get more knowledge in this wonderful world of “Microservices architecture”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;In this chapter, the following topics will be covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Understanding HTTP protocols&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understanding the request-response model in HTTP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understanding the Purpose of Different HTTP Methods GET, POST, PUT, and DELETE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understanding REST APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Best practices to define our APIs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding HTTP protocol&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In the realm of software development, particularly in web development, “HTTP protocols” stand as a fundamental pillar. This concept plays a vital role in facilitating communication between clients and servers, making it crucial to comprehend how data is transmitted and interactions are executed on the web. Thus, learning about these protocols becomes an essential aspect of understanding web development.&lt;/p&gt;

&lt;p&gt;In this topic, we will delve into the characteristics and usage of HTTP protocols, placing special emphasis on the request-response model that serves as the foundation of this architecture. Gaining a thorough understanding of how requests and responses are established and managed is of utmost importance in the development of efficient and effective web applications.&lt;/p&gt;

&lt;p&gt;Throughout this chapter, we will explore another crucial aspect related to HTTP methods, including GET, POST, PUT, and DELETE. By delving into their specific purposes and use cases, we aim to shed light on the fundamental roles they play in client-server interaction. Understanding how each method operates empowers developers to create more versatile and capable web applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Understanding the request-response model in HTTP&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The HTTP request-response model plays a pivotal role in facilitating communication between web components, acting as clients and servers. When a client sends an HTTP request to the server, the latter responds with the requested data or confirms the result of the action required. This approach ensures a seamless and efficient interaction between users and online systems, enhancing the overall user experience.&lt;/p&gt;

&lt;p&gt;Figure 2.1 shows how this communication flow is established. There the client is the web application and the server is one of the microservices defined for an e-commerce system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2ARYSKkwOfBvAJH-dI" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2ARYSKkwOfBvAJH-dI" alt="***Figure 2.1**: request-response model*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To gain a deeper understanding of how this model operates, let’s analyze each step involved, from the initial request to the final response. By delving into the intricacies of each stage, can be uncovered the underlying mechanics that enable a smooth flow of communication between clients and microservices.&lt;/p&gt;

&lt;p&gt;When a client needs to access a resource, be it a web page, a file, or a microservice that will respond, it initiates the process by sending an HTTP request to the server. This request contains the address or URL of the specific resource it requires access to. Depending on the nature of the operation, the request can take various forms, such as a GET method to retrieve information, a POST method to send data to the server, a PUT method to update an existing resource, or a DELETE method to remove a resource.&lt;/p&gt;

&lt;p&gt;If you have any concerns or doubts about these HTTP methods, rest assured that we will explore each of them in detail later in this chapter. By gaining a thorough understanding of how each method functions, you’ll be well-equipped to make use of them effectively in your web development and microservices projects.&lt;/p&gt;

&lt;p&gt;Once the server receives the client’s request, it proceeds to process the request and searches for the requested resource. If the resource is found, the server generates an HTTP response containing the requested data or a confirmation of the action’s outcome. Additionally, the response includes an HTTP status code that signifies the success of the request or indicates if an error has occurred during the process. This status code provides valuable information to the client, enabling it to interpret and handle the response appropriately based on the result of the operation.&lt;/p&gt;

&lt;p&gt;Upon receiving the server’s response, the client proceeds to process the data or information provided. If the response contains HTML code, as is the case with web pages, the browser interprets the received code and renders the page for the user to view. On the other hand, when the client consumes a microservice, it extracts and utilizes the data that was requested during the initial request. This data can then be further processed or presented to the user, depending on the specific needs of the client application. This seamless exchange of data between client and server enables efficient data transfer in microservices-based systems.&lt;/p&gt;

&lt;p&gt;Figure 2.2 shows the flow described above there can be seen the interaction between the client and server as well as the different methods in action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2Au8foe0acN2tqA63g" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2Au8foe0acN2tqA63g" alt="***Figure 2.2**: request-response complete interaction between client and server.*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The request-response model plays a vital role in enabling efficient interaction between users and online systems. By adhering to this approach, users can seamlessly access the information and resources they require, leading to a smooth and user-friendly experience. The widespread adoption of this model has paved the way for the development of a diverse array of applications and services that enrich our daily lives on the web. Its effectiveness in facilitating real-time communication between clients and servers has revolutionized the way we interact with digital platforms, empowering us to navigate the vast expanse of the internet with ease and convenience.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, the request-response model involves two essential components: the client and the server. To ensure its proper functionality, certain key elements are necessary. Let’s delve into each of these elements in the following sections.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Key elements for client-side&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Method&lt;/strong&gt;&lt;br&gt;
Indicates the type of action to be performed on the server. The most common methods are GET, POST, PUT, and DELETE, among others. Each method has a specific purpose and is intended to perform particular actions on the server.&lt;/p&gt;

&lt;p&gt;**URL (Uniform Resource Locator)&lt;br&gt;
**It is the address that identifies the resource that the client wishes to access or manipulate on the server. It can be a web page, a file, a service, or any other resource available on the server.&lt;/p&gt;

&lt;p&gt;**Headers&lt;br&gt;
**These are metadata that provide additional information about the request, such as customer information, content preferences, or cookies.&lt;/p&gt;

&lt;p&gt;**Request Body (Optional depending on the method)&lt;br&gt;
**Certain HTTP methods, such as POST and PUT, provide the capability to include additional data within the request body. This feature is particularly useful for transmitting data from the client to the server, especially when performing operations that require data submission.&lt;br&gt;
As developers, we must carefully handle and process data received in the request body to ensure data integrity and security. Proper validation and parsing of the request body data are essential to prevent security vulnerabilities and ensure that the server processes the information accurately.&lt;br&gt;
For example, when a user submits a form on a web page, the form data is typically included in the body of a POST request. The data within the request body can be in various formats, such as JSON, XML, or form-encoded data, depending on the application’s requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Key elements for server-side&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;**Status Code&lt;br&gt;
**The status code is a three-digit number that communicates the outcome of the request. It serves as a standardized way for servers to convey the result of a client’s request. Some common status codes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;200 OK&lt;/strong&gt;: Signifies a successful request, indicating that the server has fulfilled the client’s request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;404 Not Found&lt;/strong&gt;: Indicates that the requested resource could not be found on the server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;500 Internal Server Error&lt;/strong&gt;: Points to an error on the server’s side, indicating that something went wrong while processing the request.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Status codes provide valuable information to clients about the success or failure of their requests, enabling them to react accordingly. A wide range of status codes caters to various scenarios, facilitating effective communication between clients and servers in the HTTP protocol. As developers, understanding and interpreting these status codes is crucial for troubleshooting and providing meaningful feedback to users about the status of their requests.&lt;/p&gt;

&lt;p&gt;**Headers&lt;br&gt;
**Similar to the request, the response can also include headers that offer additional information about the request result or the content being returned. Headers play a vital role in providing crucial metadata, such as content type, cache control, authentication details, and more, which help both the client and server understand and process the response effectively. Utilizing headers appropriately enhances communication and enables seamless handling of data between the client and server.&lt;/p&gt;

&lt;p&gt;**Response Body&lt;br&gt;
**The response body plays a crucial role in delivering the actual content and data to the client, enabling the user interface to render the information appropriately. When a client sends a request, the server processes the request and generates the appropriate response, encapsulating the desired information within the response body.&lt;/p&gt;

&lt;p&gt;As developers, we carefully construct the response body to ensure it accurately reflects the client’s request, delivering the expected content in a well-structured and organized format.&lt;/p&gt;

&lt;p&gt;For instance, if the client requested a web page, the response body would contain the HTML code representing the content of that page. Similarly, for API requests, the response body could contain JSON or XML data containing the requested information.&lt;/p&gt;

&lt;p&gt;The request-response model is a crucial concept in web communication, playing a fundamental role in the interaction between clients and servers through the HTTP protocol. It establishes a standard and well-defined structure for communication between systems, enabling efficient and consistent data transfer.&lt;/p&gt;

&lt;p&gt;Through skillful application of this model, developers can create efficient, scalable, and reliable systems that cater to evolving user demands and provide an exceptional user experience in the vast and dynamic world of the web.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding the Purpose of Different HTTP Methods&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3684%2F1%2A_s_nJBkqn5hfMVIPeSWZcQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3684%2F1%2A_s_nJBkqn5hfMVIPeSWZcQ.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we delve into HTTP methods, let’s take a moment to review their origin and historical development over the years. Understanding the evolution of these methods provides valuable insights into how they have been refined and adapted to meet the changing needs of web development and communication between clients and servers.&lt;/p&gt;

&lt;p&gt;HTTP methods have their origin in the development of the HTTP protocol (Hypertext Transfer Protocol), which was proposed by Tim Berners-Lee in 1989 and formalized by the World Wide Web Consortium (W3C) in 1991. The HTTP protocol was born to facilitate communication and data exchange between clients and servers in the emerging World Wide Web.&lt;/p&gt;

&lt;p&gt;In its early days, the web consisted primarily of text documents, and the HTTP protocol allowed the transfer of these documents between the servers that stored them and the web browsers that requested them. As the web began to grow and become more complex, it was necessary to define a series of standardized actions to achieve a more sophisticated interaction with the servers. This evolution of the web and the need to cover this need gave rise to the HTTP methods, which from that moment became the fundamental verbs of the protocol, defining the operations that clients could carry out on web resources. Thanks to the global standardization and adoption of the HTTP protocol and its methods, the web has experienced exponential growth and has become a universal platform for accessing and distributing information around the world.&lt;/p&gt;

&lt;p&gt;Throughout this period and evolution, it has gone from only having traditional methods such as GET and POST, to a complete switch to which methods such as PUT, DELETE, and PATCH were added, expanding the possibilities of interaction and operations between client-servers. Even today, HTTP methods continue to be an essential part of web communication and have evolved to fit today’s needs.&lt;/p&gt;

&lt;p&gt;Now that we have gained insights into the origins of HTTP methods, let’s proceed to define and analyze each one of them in detail.&lt;/p&gt;

&lt;p&gt;The HTTP methods, often referred to as verbs or actions, play a crucial role in conveying the client’s intent when requesting a web server. These methods serve to define the operations that can be performed on resources identified by their URLs (Uniform Resource Locators).&lt;/p&gt;

&lt;p&gt;Each HTTP method represents a distinct set of actions that clients can undertake on web resources, facilitating diverse interactions between applications and servers across the web. With each method having well-defined semantics and usage, web applications can communicate consistently and coherently throughout the vast World Wide Web environment. This commitment to well-established methods ensures a seamless exchange of information between clients and servers, promoting robust interoperability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The HTTP methods available for use are as follows:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DELETE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HEAD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OPTIONS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PATCH&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TRACE&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;GET Method&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The GET method holds a fundamental place among the verbs in the HTTP (Hypertext Transfer Protocol) protocol, representing one of the most common actions that clients can take when interacting with web servers. As a cornerstone of web communication, the GET method allows clients to retrieve information and resources from servers, playing a pivotal role in enabling seamless data access and content delivery across the World Wide Web.&lt;/p&gt;

&lt;p&gt;The GET request is considered idempotent, which signifies that making multiple identical GET requests to the same resource does not result in any side effects on the server or alter the resource’s state. Consequently, the server should consistently respond in the same manner to each of these identical GET requests, ensuring predictability and consistency in the retrieval of information from the resource.&lt;/p&gt;

&lt;p&gt;The idempotent nature and absence of side effects make the GET method a safe and reliable option for retrieving information from web servers. Whether it’s fetching a web page, an image file, a JSON document, or any other resource identified by a URL (Uniform Resource Locator), the GET method plays a crucial role in facilitating the exchange of information that occurs daily on the Internet. Its widespread use and reliability have made it an essential part of modern web communication, empowering users to access a diverse range of resources with confidence and ease.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features of the GET method:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**Data Request&lt;br&gt;
**As mentioned the main purpose of this method is to obtain data from the server. For example, when a user clicks a link or enters a URL in the browser, a GET request is made to retrieve the content associated with that URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Query Parameters&lt;br&gt;
**A GET request can include query parameters as part of the URL to specify additional criteria or details about the request.&lt;br&gt;
For example, when performing a search, the search criteria can be included in the URL as query parameters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**URL Visibility&lt;br&gt;
**Since the query parameters are included in the URL, the GET request is visible, which means that the data sent in the GET request can be exposed, so it is not recommended to use it to transmit sensitive information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Security&lt;br&gt;
**Since GET requests are visible in the URL and may be recorded in server logs or browser history, they should not be used to send sensitive or confidential data, as they could be accessible to unauthorized third parties.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Browser Cache&lt;br&gt;
**Due to its idempotent nature and no side effects, browsers tend to cache responses from GET requests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;POST Method&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The POST method is another fundamental verb in the HTTP (Hypertext Transfer Protocol) protocol, playing a crucial role in facilitating the exchange of data between clients and servers. Unlike the GET method, which is primarily used to retrieve data from a resource, the POST method is designed to send data to the server for processing. This enables clients to perform actions that modify the state of resources on the server.&lt;/p&gt;

&lt;p&gt;The non-idempotent nature of the POST method, combined with its capability to include data in the request body, renders it suitable for a wide range of tasks. These include creating new resources, submitting forms, and transmitting sensitive information securely to the server. By leveraging the POST method, web applications can achieve complex interactions and enable users to submit data seamlessly, contributing to a rich and interactive user experience.&lt;/p&gt;

&lt;p&gt;When a client sends a POST request to a server, the data is included in the request body, distinguishing it from the GET method, where data is part of the URL. The POST request can contain a diverse range of information from submitting user inputs to uploading files or transmitting complex data structures, such as form data, user data, attachments, and other structured data in various formats like JSON or XML.&lt;/p&gt;

&lt;p&gt;By utilizing the POST method, web applications can efficiently interact with servers and facilitate sophisticated data exchanges that contribute to a dynamic and responsive user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features of the POST method:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**Sending Data&lt;br&gt;
**The main purpose of the POST method is to send data to the server for processing. For example, when submitting a form on a website, the data entered by the user is sent to the server via a POST request for processing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Data in the Request Body&lt;br&gt;
**Unlike GET, where the data is included in the URL, in POST the data is sent in the body of the HTTP request. This allows you to send larger amounts of more complex data in a structured way.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Resource Creation&lt;br&gt;
**The POST method is commonly used to send data that will create new resources on the server. For example, when publishing a new product, a POST request is made to submit the product details and create a new entry in the server’s database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Request Length&lt;br&gt;
**The length of the data sent in the POST request can be considerably longer compared to GET requests, which are generally limited in length due to the query parameters that are included in the URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Not idempotent&lt;br&gt;
**Unlike the GET method, the POST method is not idempotent, which means that making the same POST request multiple times can have different effects or change the state of the resource on the server. For example, if a POST request is sent to create a new resource, each request will create a new resource with an identifier that makes it different from the others.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Security&lt;br&gt;
**Since the data is sent in the request body and is not visible in the URL, the POST method provides an additional layer of security compared to GET. This makes it suitable for sending sensitive data, such as passwords or credit card information since the data is not exposed in the browser’s address bar.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;PUT Method&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The PUT method is another fundamental verb in the HTTP (Hypertext Transfer Protocol) protocol. Its primary purpose is to transmit data from the client to the server to update or replace an existing resource on the server. In contrast to the POST method, which is used for creating new resources, the PUT method is specifically designed for modifying existing data on the server.&lt;/p&gt;

&lt;p&gt;By leveraging the PUT method, clients can efficiently update or replace resource representations, ensuring data accuracy and consistency in web applications and systems. This method plays a crucial role in enabling effective resource management and facilitating seamless interactions between clients and servers in HTTP.&lt;/p&gt;

&lt;p&gt;It is idempotent, which ensures that making multiple identical PUT requests has no additional side effects beyond updating the resource. The PUT method is essential for web applications that require the ability to modify existing data and maintain the integrity of resources on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features of the PUT method&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**Resources Update&lt;br&gt;
**The main purpose of the PUT method is to update or replace an existing resource on the server with new data provided by the client. For example, a customer can use the PUT method to update user profile information, modify shipping addresses, or update product stock.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Resource Identification&lt;br&gt;
**To make a PUT request, the client must provide the URL of the specific resource that it wants to update. The server uses this URL to identify the resource to be modified, the identifier should be part of the URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Data in the Request Body&lt;br&gt;
**The PUT is similar to POST request, in PUT the data is sent in the body of the HTTP request. This allows you to send larger amounts of more complex data in a structured way that will be used to update the existing values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Idempotence&lt;br&gt;
**Like the GET method, the PUT method is idempotent, which means that making an identical PUT request to the same resource multiple times should have no additional side effects beyond updating the resource with the new data provided. Each identical PUT request updates the resource with the same data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**No Browser Cache&lt;br&gt;
**Like the POST method, browsers generally do not cache responses from PUT requests, as they can have side effects on the server, changing the state of an existing resource.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Security&lt;br&gt;
**As with any HTTP method, it’s important to keep security considerations in mind when using PUT. PUT requests can have a significant impact on data on the server, so it is critical to apply proper authentication and authorization mechanisms to protect resources from unauthorized modification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Not Visible in URL&lt;br&gt;
**Like the POST method, the data sent with the PUT method is not visible in the URL. The data is sent in the body of the HTTP request, providing greater privacy and security for the transmission of information.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;PATCH Method&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The PATCH method is another essential verb in the HTTP (Hypertext Transfer Protocol) protocol, enabling the client to send data to the server to apply partial modifications to an existing resource.&lt;/p&gt;

&lt;p&gt;In contrast to the PUT method, which is utilized to entirely update or replace a resource, the PATCH method offers the flexibility to make partial or specific changes to the content of the resource. This targeted approach allows developers to modify specific attributes or sections of a resource without the need to send the entire representation, thus optimizing the data exchange process.&lt;/p&gt;

&lt;p&gt;The PATCH method is particularly valuable in scenarios where resources are extensive, and only specific updates are required. By leveraging the PATCH method, web applications can efficiently manage resource updates, minimizing data transfer and reducing the chances of conflicting modifications from multiple clients. This granular control over resource updates enhances the efficiency and responsiveness of web services, contributing to a smoother user experience and streamlined resource management on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features of the PATCH method:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**Partial Modifications&lt;br&gt;
**The main purpose of the PATCH method is to apply partial or specific changes to the content of a resource on the server. This means that instead of sending all of the resource data in the request, the client only sends the changes or updates that you want to make to the existing resource.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Resource Identification&lt;br&gt;
**Similar to the PUT and POST methods, to make a PATCH request, the client must provide the URL of the specific resource that it wants to modify, where the identifier is part of that URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Idempotence&lt;br&gt;
**Although the PATCH method is not guaranteed to be idempotent by default, it can be designed to be idempotent if the server is configured to do so. This means that when making multiple identical PATCH requests to the same resource, the result should be the same, and no additional side effects should be applied.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Security&lt;br&gt;
**As with any HTTP method, it is important to be aware of security when using PATCH. Since PATCH can modify only a specific part of the resource, it is essential to apply proper authentication and authorization mechanisms to protect resources from unauthorized modification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Not Visible in URL&lt;br&gt;
**As with the POST and PUT methods, the data sent with the PATCH method is not visible in the URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Data in the Request Body&lt;br&gt;
**Changes are sent in the body of the HTTP request, providing greater privacy and security for the transmission of information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**No Browser Cache&lt;br&gt;
**Like the POST and PUT methods, responses from PATCH requests are generally not cached by browsers, as they can have side effects on the server, partially modifying the state of an existing resource.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;DELETE Method&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The DELETE method is another vital verb in the HTTP (Hypertext Transfer Protocol) protocol, serving as a means to request the deletion of a specific resource on the server. Its primary purpose is to instruct the server to remove the designated resource from its storage.&lt;/p&gt;

&lt;p&gt;As the method specifically intended for deleting resources on the web server, the DELETE method plays a crucial role in managing and maintaining the state of resources in web applications. By utilizing the DELETE method, clients can efficiently initiate the removal of unnecessary or obsolete data, promoting efficient resource management and data cleanup on the server.&lt;/p&gt;

&lt;p&gt;This capability is especially valuable for applications that handle user-generated content, data archiving, or any scenario where the removal of resources is required to maintain system performance and data integrity. The DELETE method’s well-defined purpose and standardized implementation enable developers to design robust and secure systems, ensuring the appropriate handling of resource deletions and enhancing the overall functionality of web applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features of the DELETE method:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**Resource Removal&lt;br&gt;
**The main purpose of the DELETE method is to delete a specific resource on the server. When a client sends a DELETE request it is telling the server to delete the resource associated with that URL, that resource is associated with a unique identifier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Idempotence&lt;br&gt;
**Like the GET method, the DELETE method is also idempotent. This means that making multiple identical DELETE requests to the same resource has no additional side effects beyond deleting the resource once.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Security&lt;br&gt;
**Since the DELETE method involves a destructive action on the server, it is essential to apply proper authentication and authorization mechanisms to protect resources from unauthorized deletion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**No Browser Cache&lt;br&gt;
**Like the POST, PUT, and PATCH methods, browsers generally do not cache responses to DELETE requests, since a deleted item is typically no longer accessible to users.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;HEAD Method&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The HEAD method is one of the helper verbs in the HTTP (Hypertext Transfer Protocol) protocol, this verb is very similar to the GET method. However, the HEAD method is used to request only the headers of an HTTP response, not including the message body. In other words, the HEAD method allows a client to get information about a resource without downloading all of its content, making it useful for performing quick availability checks, getting metadata information, or validating the existence of a resource.&lt;/p&gt;

&lt;p&gt;By its nature the HEAD method is a lightweight alternative to the GET method, ideal for checking the availability of a resource, obtaining metadata information, and performing quick checks on the existence of resources without downloading all their content. Its idempotency and efficiency make it a valuable option in certain scenarios where the client needs limited information about a resource.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features of the HEAD method:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**Getting Headers&lt;br&gt;
**The main purpose of the HEAD method is to get the headers of an HTTP response without receiving the response body, these headers may contain important information about the resource.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**light response&lt;br&gt;
**The HEAD method is especially useful when the client only needs to get information about the resource without downloading all the content.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Resource Identification&lt;br&gt;
**Like the other HTTP verbs that have been reviewed, the client must provide the URL of the specific resource from which it wants to get the headers. The server uses this URL to identify the resource and generate a response with the requested headers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Idempotence&lt;br&gt;
**Like the GET and DELETE methods, the HEAD method is also idempotent. Making multiple identical HEAD requests to the same resource has no additional side effects, and the server must provide the same headers in response to repeated requests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;OPTIONS Method&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The OPTIONS method is one of the verbs in the HTTP (Hypertext Transfer Protocol) protocol. This is used to obtain information about the options and capabilities that are supported by a specific resource on the server, its main purpose being to provide a clear and detailed description of the options allowed for a resource without making requests that have side effects on the server.&lt;/p&gt;

&lt;p&gt;The OPTIONS method is considered as a non-standard request and is mainly used to allow clients to obtain details about the functionality and configurations supported by a server, which can be useful for interoperability and service discovery in complex web applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features of the OPTIONS method&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**Informative Response&lt;br&gt;
**The response to an OPTIONS request contains information in the form of HTTP headers indicating the options supported by the server for the requested resource. These headers include “Allow”, which lists the allowed HTTP methods, and other custom headers that the server can include to provide additional details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Resource Identification&lt;br&gt;
**As with the other HTTP methods, the client must provide the URL of the specific resource from which it wishes to obtain the options. The server uses this URL to identify the resource and generate a response with the requested information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**No Browser Cache&lt;br&gt;
**Like the HEAD and DELETE methods, browsers generally do not cache responses from OPTIONS requests, as this information can change and is required for real-time interaction with the server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;TRACE Method&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The TRACE method is one of the verbs in the HTTP (Hypertext Transfer Protocol) protocol, primarily employed for diagnostic and debugging purposes. Its main function is to enable clients to obtain a “trace” of the route a request takes from the client to the server and back, including all intermediaries (proxies) encountered along the way.&lt;/p&gt;

&lt;p&gt;This feature proves useful for tracing the path of a request through various servers and proxies to verify the integrity and routing of the requests. However, due to its potential for vulnerabilities, many servers disabled support for the TRACE method by default for security reasons.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding REST APIs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5120%2F0%2ArKhhXGsN2ZaCrmif.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5120%2F0%2ArKhhXGsN2ZaCrmif.jpg" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the world of software development, more specifically in web development, “REST-based Application Programming Interfaces” (REST APIs) have revolutionized the way applications and services communicate and interact with each other. Since their inception, REST APIs have become a fundamental pillar for the creation of applications, allowing different systems to connect and share data efficiently and securely.&lt;/p&gt;

&lt;p&gt;In this topic, will be studied the main characteristics and key points of REST APIs will be studied. We will learn how REST APIs are based on the REST (Representational State Transfer) protocol, allowing for a flexible and lightweight architecture that adapts to a wide range of use cases.&lt;/p&gt;

&lt;p&gt;In addition, we will discover the best practices for designing and building robust, secure, and high-performance REST APIs. From creating clear paths and resources to proper error handling and authentication, we’ll explore the most effective techniques for delivering a smooth user experience and seamless interaction between apps and services.&lt;/p&gt;

&lt;p&gt;To begin let’s see what the REST APIs are. An “Application Programming Interfaces” (APIs) are a set of rules and protocols that allow different computer systems to communicate and share data over the Internet in a standardized manner. The term “REST” comes from “Representational State Transfer” and is a style of software architecture that is widely used in web application development.&lt;/p&gt;

&lt;p&gt;REST APIs are based on the HTTP (Hypertext Transfer Protocol) protocol, which is the protocol used to transmit data on the web. They follow a set of principles and constraints that promote simplicity, scalability, efficiency, and interoperability between systems.&lt;/p&gt;

&lt;p&gt;Being related to the HTTP protocol, the actions of the REST APIs are linked to its standard methods, such as GET (to get data), POST (to create new resources), PUT (to update existing resources), and DELETE (to delete resources). ). Each one with the characteristics mentioned above.&lt;/p&gt;

&lt;p&gt;REST APIs are widely used in web and mobile application development, as they allow different applications to connect and share data efficiently and securely. By following REST principles, these APIs become easier to understand, use, and maintain, which has led to their popularity in the software development community.&lt;/p&gt;

&lt;p&gt;To understand REST APIs, it is important to learn and understand the following key points since each of them is part of the REST APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;REST&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;“&lt;/strong&gt;Representational State Transfer”, commonly known as REST, is a crucial concept to grasp in understanding the fundamentals of REST architecture. It revolves around the appropriate utilization of HTTP methods and the design of web resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Resource&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The resources are the foundation of REST APIs, representing identifiable and addressable elements or entities on the web. Each resource is uniquely identified by a URL (Uniform Resource Locator), enabling access, creation, updating, or deletion through various HTTP methods (GET, POST, PUT, DELETE, and more).&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;URIs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The “Uniform Resource Identifiers” (URIs) are used to uniquely identify each resource in the REST API. They are the URLs that allow you to access and manipulate the resources. In addition, URIs help to follow a specific format and represent a hierarchical structure that reflects the organization of resources in the system.&lt;/p&gt;

&lt;p&gt;For example,*** &lt;a href="https://example.com/products" rel="noopener noreferrer"&gt;https://example.com/products&lt;/a&gt;***&lt;/p&gt;

&lt;p&gt;The combination of URIs and HTTP methods allows a RESTful API to offer a uniform and consistent interface for interacting with resources. This makes the API easier to understand and use, as clients only need to know the URIs and methods to interact with different parts of the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;HTTP methods&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The HTTP methods are directly related to REST APIs since HTTP methods are used to perform operations on resources identified by URLs (Uniform Resource Locators).&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;HTTP responses&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Understanding HTTP status codes, which indicate the result of a request, is crucial for developing applications that implement REST APIs.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;200 OK — Request Success&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;201 Created — Resource created success&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;204 No Content — Successful request with no content to return&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;400 Bad Request — Incorrect or invalid request&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;401 Unauthorized — Not authorized to access the resource&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;403 Forbidden — Access to the resource is prohibited&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;404 Not Found — Resource not found&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;405 Method Not Allowed — Method not allowed for the resource&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;500 Internal Server Error — Internal server error&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;503 Service Unavailable — Service not available&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;CRUD Operations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The CRUD is an acronym that stands for the four basic operations on resources: Create, Read, Update, and Delete.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;JSON&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;SON is a lightweight, easy-to-read data exchange format widely used in REST APIs to represent information.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Authentication and Authorization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As an essential part of the security of our REST APIs, it is crucial to understand how access to resources is secured through authentication and authorization, which allows only users and groups of users to access specific resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;API Version&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Adding a version helps ensure compatibility with different versions of the API and prevent disruption for existing customers. Example:&lt;/p&gt;

&lt;p&gt;API defined with Version 1: &lt;a href="https://example.com/v1/products" rel="noopener noreferrer"&gt;***https://example.com/v1/products&lt;/a&gt;***&lt;/p&gt;

&lt;p&gt;API defined with Version 2: &lt;a href="https://example.com/v2/products" rel="noopener noreferrer"&gt;***https://example.com/v2/products&lt;/a&gt;***&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Documentation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Clear and complete documentation is essential for developers to be able to use a REST API smoothly and take full advantage of its capabilities. We can help each other with tools like OpenAPI.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;RESTful Design Patterns.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Get familiar with RESTful design patterns to ensure a consistent and well-structured architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;These patterns are listed as follows:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hierarchical URI Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API Versioning Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pagination Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Filter and Search Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HATEOAS (Hypermedia as the Engine of Application State) pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cache Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authentication and Authorization Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error Handling Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Push Notification Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API Gateway Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rate Limiting Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nested Resource Pattern&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resource Composition Pattern&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Best practices to define our APIs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A-gCptpHpgUbOfo-SgsjBMQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A-gCptpHpgUbOfo-SgsjBMQ.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the realm of API development, the design of a REST API is crucial to its success and efficiency. Best practices for defining REST APIs provide guidelines and approaches to create robust interfaces that are user-friendly and comprehensible for consumers.&lt;/p&gt;

&lt;p&gt;These practices enhance interactions between clients and servers while bolstering scalability, security, and maintainability throughout the API’s lifespan. In this subtopic, we will explore key best practices for effectively designing REST APIs, ensuring seamless integration into diverse applications and services.&lt;/p&gt;

&lt;p&gt;Following are listed the main best practices that help to develop good APIs:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Always use plural names to identify resources in the URLs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For example, instead of using “&lt;em&gt;**/product&lt;/em&gt;&lt;em&gt;”&lt;/em&gt;, opt for “&lt;strong&gt;&lt;em&gt;/products&lt;/em&gt;&lt;/strong&gt;”. This consistent naming convention improves the clarity and intuitiveness of your REST API, making it easier for developers to understand and work with the resources. Additionally, using plural names aligns with standard RESTful practices, promoting consistency and better communication between clients and servers.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Using HTTP Methods Semantically&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ensure the appropriate and consistent use of HTTP methods to reflect CRUD (Create, Read, Update, Delete) operations on resources. For example, use POST to create resources, PUT to update them, and DELETE to delete them. By adhering to these semantic conventions, you enhance the clarity and predictability of your REST API, making it easier for developers to understand and interact with the different resources.&lt;/p&gt;

&lt;p&gt;Properly utilizing HTTP methods promotes a standardized and efficient way of communicating with your API, ensuring a smooth and effective experience for clients and servers alike.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Maintain Hierarchy in URLs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Organize URLs in a hierarchical and meaningful manner to represent the relationships between resources effectively.&lt;/p&gt;

&lt;p&gt;For example, use a structure like “&lt;em&gt;**/users/{userId}/orders&lt;/em&gt;&lt;em&gt;”&lt;/em&gt; to retrieve the orders associated with a particular user. This practice fosters consistency and clarity in your REST API, leading to improved usability and a smoother development experience, making it easier for developers to navigate and understand the relationships between various resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Version the API&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;By incorporating the version number directly into the URL to ensure future compatibility. For example, utilize “&lt;strong&gt;&lt;em&gt;/v1/products&lt;/em&gt;&lt;/strong&gt;” to represent version 1 of the Products API.&lt;/p&gt;

&lt;p&gt;By versioning the API in this manner, you create a clear distinction between different versions, enabling clients to access the desired version while avoiding potential disruptions in functionality due to changes in future versions. This practice promotes a seamless and robust evolution of your API over time, providing developers with the flexibility to upgrade to newer versions at their own pace while maintaining backward compatibility when necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Use Appropriate HTTP Status Codes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Implementing the appropriate HTTP status codes to accurately indicate the outcome of each request. For example, utilize 200 OK for successful responses and 404 Not Found for resources that cannot be located.&lt;/p&gt;

&lt;p&gt;By using HTTP status codes judiciously, you convey crucial information about the state of the request to clients, facilitating proper handling of responses and error scenarios. This practice ensures that clients can effectively interpret and respond to different outcomes during their interactions with the API.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Avoid Verbs in URLs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Avoid incorporating verbs in URLs and stick to using only nouns to represent resources. For instance, prefer “&lt;strong&gt;&lt;em&gt;/products&lt;/em&gt;&lt;/strong&gt;” over “&lt;strong&gt;&lt;em&gt;/create-product&lt;/em&gt;&lt;/strong&gt;” when creating a new user.&lt;/p&gt;

&lt;p&gt;This principle aligns with the proper implementation of HTTP methods, where the HTTP method itself conveys the action to be performed on the resource. This approach simplifies the URL structure and ensures that the focus remains on the resource itself rather than the action being taken, enhancing the overall readability and usability of your REST API.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Allow clients to filter, sort, and paginate results to handle large data sets&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Enable clients to filter, sort, and paginate results to efficiently manage large data sets. By providing these functionalities in your REST API, you empower clients to retrieve only the specific data they require, improving the performance and usability of the API. Filtering allows clients to narrow down results based on specific criteria while sorting enables them to order the data in a preferred manner. Pagination enables clients to retrieve data in smaller, manageable chunks, reducing the load on both the client and the server.&lt;/p&gt;

&lt;p&gt;Use query parameters that allow for flexible data filtering.&lt;/p&gt;

&lt;p&gt;For example: “&lt;strong&gt;&lt;em&gt;/products?price=30&lt;/em&gt;&lt;/strong&gt;” or “&lt;strong&gt;&lt;em&gt;/products?active=false&lt;/em&gt;&lt;/strong&gt;”.&lt;/p&gt;

&lt;p&gt;**Protect the API with Authentication and Authorization&lt;br&gt;
**Secure your API by implementing authentication and authorization mechanisms to control resource access.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Document the API&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Provide clear and complete documentation of the API, including sample requests and responses, to facilitate its use by developers.&lt;/p&gt;

&lt;p&gt;Thoroughly documenting the API is crucial because it provides developers with all the necessary information to use it effectively. Comprehensive documentation explains how to interact with resources, which parameters are required, what responses to expect, and how to handle errors.&lt;/p&gt;

&lt;p&gt;Having well-structured and accessible documentation allows developers to quickly grasp the API’s functionality, saving time and reducing the learning curve.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Error Handling&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Error handling is a critical aspect of a robust API. When an error occurs, it’s essential to provide clear and detailed error responses to the clients. These error responses should include concise yet highly descriptive error messages, along with the appropriate HTTP status code, which accurately reflects the nature of the error.&lt;/p&gt;

&lt;p&gt;By offering comprehensive error information, developers can quickly identify the issue and take appropriate actions to resolve it. Well-designed error handling enhances the overall user experience, as it reduces the frustration caused by vague error messages and assists developers in troubleshooting and debugging their applications effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Separate words with hyphens (-)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Use hyphens to separate words when defining resource names that consist of multiple words. For example, if our resource represents “products best sellers” it is recommended to structure the URL as /products/best-sellers, etc.&lt;/p&gt;

&lt;p&gt;This practice, known as “kebab-case,” enhances the readability and clarity of your API URLs which creates a consistent and visually appealing URL structure, promoting better communication between clients and servers and improving the overall user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Significant names&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Choose meaningful and descriptive names for your resources and endpoints. This practice greatly enhances the usability of your API for developers, as it ensures that the purpose and functionality of each resource or endpoint are immediately apparent. By using significant names, you create a self-explanatory API that reduces the need for extensive documentation and enables developers to work more efficiently. Well-chosen names also contribute to the maintainability and scalability of the API, as they promote consistency and coherence throughout the design. Ultimately, prioritizing descriptive names simplifies the development process and fosters a seamless experience for those interacting with your API.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Avoid too-long names&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Avoid using overly long names for resources and endpoints in your API. Lengthy names can create usability and readability issues, making the API cumbersome to work with and maintain. By keeping names concise and focused, you improve the developer experience and promote a clearer understanding of the API’s structure and functionality.&lt;/p&gt;

&lt;p&gt;Additionally, shorter names contribute to cleaner and more organized code, making it easier for developers to manage and update the API in the future. Striking the right balance between descriptive and succinct names ensures an API that is user-friendly, efficient, and sustainable in the long run.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Avoid confusing abbreviations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Avoid abbreviations that may be confusing or unintuitive to developers consuming the API. It is better to opt for clear and descriptive names.&lt;/p&gt;

&lt;p&gt;Avoid using confusing or unintuitive abbreviations in your API. Instead, opt for clear and descriptive names that make the API more user-friendly and easier to understand for developers. Ambiguous abbreviations can lead to misunderstandings and errors when consuming the API, while explicit names provide clarity and promote consistency.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;HATEOAS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Consider implementing HATEOAS (Hypermedia as the Engine of Application State) in your API design. HATEOAS allows you to include hypermedia links in API responses, enabling clients to dynamically navigate and discover available resources and actions. By providing these links, clients can interact with the API more seamlessly, reducing the need for prior knowledge of resource URIs. This approach promotes a more flexible and self-descriptive API, allowing developers to build more adaptable and resilient applications. Embracing HATEOAS fosters a more discoverable and intuitive API experience, encouraging better client-server interaction and facilitating future API updates and expansions.&lt;/p&gt;

&lt;p&gt;Complying with best practices for designing REST APIs is essential to ensure their success and efficiency. Implementing each of these practices is highly recommended to enhance the overall API experience and foster a more productive and collaborative environment between clients and servers.&lt;/p&gt;

&lt;p&gt;Furthermore, adhering to these guidelines ensures that our APIs will excel in areas such as ease of use, scalability, security, and maintainability. By following these rules during development, developers can create solid interfaces that seamlessly integrate with various applications and services more easily and reduce issues.&lt;/p&gt;

&lt;p&gt;Next readings …&lt;/p&gt;

&lt;p&gt;Chapter 6 “HTTP package in golang”.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Chapter 4 - Advantages of Using Go for Web Development</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Wed, 27 Sep 2023 23:55:52 +0000</pubDate>
      <link>https://dev.to/josueparra2892/chapter-4-advantages-of-using-go-for-web-development-4b0k</link>
      <guid>https://dev.to/josueparra2892/chapter-4-advantages-of-using-go-for-web-development-4b0k</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Chapter 4 - A&lt;/strong&gt;dvantages of Using Go for Web Development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Building our first webservice with Go (Part 1)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2ABR_ven7LRlI85z6GmqL8Ew.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2ABR_ven7LRlI85z6GmqL8Ew.jpeg" alt="img1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Welcome to the fourth part of this series dedicated to microservice architecture, In this chapter we start focusing our learning on Golang programming language implemented to build our microservices.&lt;/p&gt;

&lt;p&gt;In this first part will evaluate the advantages that Golang offers to be one of the most popular and better languages to be used at time to develop our microservices.&lt;/p&gt;

&lt;p&gt;The following list is the previous chapters of this series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-1-introduction-to-microservices-5a2c"&gt;Chapter 1 — Introduction to Microservices&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-2-introduction-to-microservices-part-2-479l"&gt;Chapter 2 — Introduction to Microservices (Part 2)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-3-domain-driven-design-and-microservices-371b"&gt;Chapter-3 Domain-driven design and microservices&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I recommend you take a look at the previous chapters if you have not read them yet. That will help you to get more knowledge in this wonderful world of “Microservices architecture”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This chapter will give a significant turn to this learning journey related to the construction of microservices in Go since this chapter will focus on the fundamental concepts behind the creation of a Web Service in Go, the advantages that Go offers for web development, and how it can significantly improve the productivity and performance of our applications will be analyzed.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Structure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this chapter, the following topics will be covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Introducing Go programming language&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understanding the advantages of using Go for web development&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introducing Go programming language
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2A5siDv-30C_9lN_6m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2A5siDv-30C_9lN_6m.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go, also known as Golang, is a remarkable open-source programming language introduced by Google in 2007. It was developed by Robert Griesemer, Rob Pike, and Ken Thompson, to combine efficiency and ease of use in a modern programming language.&lt;/p&gt;

&lt;p&gt;Being a compiled language, Go boasts exceptional speed and security. Its feature set includes automatic garbage collection, static typing, type inference, and an intuitive syntax that enhances code readability and writing ease. Moreover, Go presents a distinctive concurrency model, employing goroutines and channels, enabling programmers to effortlessly create concurrent and parallel programs with a high degree of safety.&lt;/p&gt;

&lt;p&gt;This powerful blend of performance, efficiency, and code clarity has propelled Golang to earn widespread recognition in the software development industry. Consequently, it has found extensive applications in building high-performance systems, web applications, services, and command-line tools. Go’s versatility and strong reputation have made it a popular choice among developers seeking to tackle complex projects while ensuring robustness and maintainability.&lt;/p&gt;

&lt;p&gt;More information related to this programming language can be found on its official website &lt;a href="https://go.dev" rel="noopener noreferrer"&gt;https://go.dev&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding the advantages of using Go for web development&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3728%2F1%2An5HNSp17QWfNCZdVGwu-cQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3728%2F1%2An5HNSp17QWfNCZdVGwu-cQ.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This topic will thoroughly examine the multitude of advantages that Go brings to web service development. Will be explored key aspects such as its impressive performance, efficient concurrency model, automatic garbage collector, robust standard library, and more.&lt;/p&gt;

&lt;p&gt;By listing these essential features, The aim is to gain valuable insights into why Go has garnered immense popularity, solidifying its position as one of the primary programming languages for building web services in the software industry. Through this exploration, Will be uncovered the remarkable capabilities that have made Go a favored choice among developers, enabling them to craft highly performant and reliable web services with ease.&lt;/p&gt;

&lt;p&gt;Golang stands out as an exceptional choice for creating web services, thanks to a powerful combination of features that are covered later in this chapter. It should be noted that thanks to its remarkable performance, it ensures that web applications are highly responsive and can handle heavy workloads with ease. In addition, thanks to its wide acceptance, Golang has strong support from the community, which provides a wealth of resources and expertise, ranging from extensive documentation, to a wide range of third-party libraries, resulting in great support for developers as they have the tools they need to overcome challenges and streamline web services development.&lt;/p&gt;

&lt;p&gt;Some of the advantages are the following:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Performance&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3708%2F1%2AR2FphR3VQVwmBxhbL25q_Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3708%2F1%2AR2FphR3VQVwmBxhbL25q_Q.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Performance is one of the most compelling aspects of Golang. With its compiled nature and efficient concurrency model, Golang brings exceptional speed and high-performance capabilities to web applications.&lt;/p&gt;

&lt;p&gt;The compiled nature of Golang allows our code to be translated into machine code, resulting in faster execution times and optimized performance. This efficiency is particularly beneficial for web applications that require quick response times and high throughput.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scalability&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As web applications grow and face higher traffic, Go’s scalability becomes a key asset, enabling seamless expansion without sacrificing performance. The golang lightweight goroutines empower to build web services that can effortlessly handle high loads and accommodate the demands of a rapidly expanding user base, making it an excellent choice for developing scalable and high-performance web applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Simplicity&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The simple and concise syntax defined by Golang makes it easy to read and maintain code, even in large codebases, it helps to reduce the learning curve, promote code cleanliness, and enhance developer productivity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3708%2F1%2AABcFd-m9afz4a4kTrFqxbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3708%2F1%2AABcFd-m9afz4a4kTrFqxbg.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Standard Library&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Go’s standard library provides a lot of essential functionalities for web development. It encompasses a wide range of comprehensive packages specifically designed to handle HTTP, JSON, encryption, and more, streamlining various web development tasks. That means that developers don’t have to rely heavily on third-party libraries for common functionalities. Whether it’s handling HTTP requests and responses, parsing and encoding JSON data, or implementing secure encryption, the standard library provides robust and reliable solutions right out of the box.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3752%2F1%2AWtswb8UwIXQP9N1mqdhSZQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3752%2F1%2AWtswb8UwIXQP9N1mqdhSZQ.png" alt="ii"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Concurrency&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Goroutines and channels offer an elegant and straightforward approach to concurrent programming, empowering developers to construct highly efficient and responsive web applications with ease. Additionally, Golang’s built-in concurrency primitives, such as channels, simplify communication and synchronization in web applications, further enhancing their reliability and performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3748%2F1%2AP2CYPUEYkkAJ6BKVoZi8Ew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3748%2F1%2AP2CYPUEYkkAJ6BKVoZi8Ew.png" alt="img 06"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Garbage Collection&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Automatic garbage collection in Go relieves developers from the burden of manual memory management, significantly reducing the risk of memory-related bugs.&lt;/p&gt;

&lt;p&gt;With automatic garbage collection, the developers no longer need to worry about deallocating memory manually, as the Go runtime takes care of identifying and reclaiming unused memory automatically. This advantage reduces the chances of memory leaks and other common memory-related issues that can plague applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3736%2F1%2AQ-zvB_ouNJ6FRmmTcEjT4A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3736%2F1%2AQ-zvB_ouNJ6FRmmTcEjT4A.png" alt="img03"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Static Typing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This characteristic helps to catch errors at compile-time, providing greater reliability and safety.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Deployment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The self-contained nature of these binaries ensures the deployment effortlessly, regardless of the target environment or configurations.&lt;/p&gt;

&lt;p&gt;This level of portability is very valuable, as it allows to distribution of the applications to different platforms and systems without the need for recompilation or complex setup procedures. Whether deploying on a local development machine, a staging server, or a production environment, the self-contained nature of Golang binaries ensures a consistent and hassle-free deployment experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3720%2F1%2AmnIx_MpWRpi8vGTx2MRHyA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3720%2F1%2AmnIx_MpWRpi8vGTx2MRHyA.png" alt="img02"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Testing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Golang offers a robust core library for testing, empowering developers to ensure code quality through automated testing. With its built-in testing framework and clear test syntax, Golang facilitates the creation of comprehensive test suites, allowing us to verify the correctness and reliability of our code effortlessly. The simplicity and effectiveness of Golang’s testing capabilities enable more reliable and maintainable applications, contributing to a seamless development experience and higher code confidence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3744%2F1%2A8M1oA-4s0at_aRVc_giKjw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3744%2F1%2A8M1oA-4s0at_aRVc_giKjw.png" alt="img01"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Error handling&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The error handling in Go is a powerful and elegant approach that promotes explicit error checking, contributing to enhanced code reliability and maintainability.&lt;/p&gt;

&lt;p&gt;By requiring developers to handle errors explicitly, Go ensures that potential issues are not overlooked, leading to more robust and resilient applications. This approach also encourages developers to write cleaner and more organized code, making it easier to understand and maintain over time.&lt;/p&gt;

&lt;p&gt;With clear and structured error handling, identifying and addressing potential problems is done very quickly, improving the overall quality and stability of our Golang projects. Embracing Go’s error-handling philosophy empowers us to build more reliable software and fosters a culture of code excellence within the development team.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Static analysis&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;in Go is an invaluable feature that greatly aids in maintaining code quality and consistency. With built-in tools such as go fmt, can be easily performed static analysis on our codebase, ensuring that it adheres to standardized formatting and identifying potential issues early in the development process.&lt;/p&gt;

&lt;p&gt;The Go fmt tool, for instance, automatically formats the code to adhere to the official Go style guide, making the codebase more readable and maintainable across the team.&lt;/p&gt;

&lt;p&gt;Embracing static analysis as a routine part of our development workflow allows us to focus on building robust and efficient applications while adhering to the best practices and conventions of the Go community.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Compilation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This point is one of the most advantageous aspects of working with Go. Its remarkable compilation speed empowers developers to iterate rapidly during the development process. This efficiency in compilation aligns perfectly with Go’s overall design philosophy of simplicity and productivity. Enabling to write and test code in shorter cycles, Helping to reduce the risk of introducing errors, and streamlining the overall development workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Resource Efficiency&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Go is meticulously designed to be lightweight and highly resource-efficient. This feature is especially beneficial for the development of microservices since these systems often operate in environments with limited resources.&lt;/p&gt;

&lt;p&gt;The streamlined nature of Go allows microservices to run efficiently and without requiring large amounts of memory or processing power. This is essential to maintain optimal performance, especially when deploying multiple microservices in a distributed environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Versatility&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is another of the standout features of Go, making it an incredibly flexible and powerful language that transcends the boundaries of web development. Beyond its exceptional capabilities for building web services, Go shines as a multipurpose language, perfectly suited for a wide range of domains.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Community and Support&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The growing Go community provides extensive resources, libraries, and support for web development. In addition, Go receives continuous improvements and updates, ensuring its long-term viability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3756%2F1%2AFurVvh3scXnHpgXZG03FFA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3756%2F1%2AFurVvh3scXnHpgXZG03FFA.png" alt="img2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Documentation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The quality of documentation on Golang is one of the key factors that have driven the adoption and popularity of the language. Since it is widely recognized for being clear, complete, and very useful as it provides excellent information about the language and its standard library, such documentation is available on the official site &lt;a href="https://go.dev/." rel="noopener noreferrer"&gt;https://go.dev/.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition to the official documentation, the Go developer community has contributed a wide variety of tutorials, guides, posts, and online examples. These additional resources allow developers to access more specialized information and share knowledge with other members of the community.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3744%2F1%2ALaYxJwwfWqZ5qYbbJvCw5Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3744%2F1%2ALaYxJwwfWqZ5qYbbJvCw5Q.png" alt="img3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Whether you’re developing a small-scale API or large-scale microservices, Golang’s strengths go into building fast, reliable, and efficient web services.&lt;/p&gt;

&lt;p&gt;Adopting Go as the programming language of choice for our web services enables developers to address the demands of modern web applications with confidence and deliver solutions that excel in both performance and maintainability.&lt;/p&gt;

&lt;p&gt;In a rapidly evolving technological landscape, the advantages that Golang offers position it as a language with a vision of the future, which guarantees long-term viability for the development of web services.&lt;/p&gt;

&lt;p&gt;As more companies and developers recognize its advantages, Golang continues to solidify its position as the best choice for building web services that provide exceptional user experiences and adapt to ever-changing demands.&lt;/p&gt;




&lt;p&gt;Next readings:&lt;/p&gt;

&lt;p&gt;Chapter 5 “Understanding HTTP Protocols and REST APIs”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-5-understanding-http-protocols-and-rest-apis-302p"&gt;https://dev.to/josueparra2892/chapter-5-understanding-http-protocols-and-rest-apis-302p&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Chapter 3 — Domain-Driven Design and Microservices</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Wed, 27 Sep 2023 23:52:46 +0000</pubDate>
      <link>https://dev.to/josueparra2892/chapter-3-domain-driven-design-and-microservices-371b</link>
      <guid>https://dev.to/josueparra2892/chapter-3-domain-driven-design-and-microservices-371b</guid>
      <description>&lt;h2&gt;
  
  
  Chapter 3 — Domain-Driven Design and Microservices
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2A036pe_66qvWOPErBr7-RLg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2A036pe_66qvWOPErBr7-RLg.jpeg" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Welcome to the third part of this series dedicated to microservice architecture.&lt;/p&gt;

&lt;p&gt;The following are the previous chapters of this series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-1-introduction-to-microservices-5a2c"&gt;Chapter 1 — Introduction to Microservices&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-2-introduction-to-microservices-part-2-479l"&gt;Chapter 2 — Introduction to Microservices (Part 2)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;In this chapter, we will discuss the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DDD and microservices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Domain-Driven Design and microservices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, let’s start with an introduction to what Domain-Driven Design is. Eric Evans introduced the idea of Domain-Driven Design in his book “Domain-Driven Design: Tackling Complexity in the Heart of Software”, where He mentions that DDD is a software development approach and methodology that aims to align the design and implementation of software systems with the complexities of the business domain they are intended to model.&lt;/p&gt;

&lt;p&gt;Domain-Driven Design emphasizes understanding and modeling of the application domain, fostering close collaboration between domain experts and developers to create a shared understanding of the business domain and its complexities by improving requirements definition, and functionalities and applying corresponding solutions to the domain under analysis.&lt;/p&gt;

&lt;p&gt;Domain-driven design and microservices architecture are closely related and often go hand in hand as each microservice is responsible for a specific domain.&lt;/p&gt;

&lt;p&gt;As was studied before, when is implemented a microservices architecture, the application is divided into small, independent services, each responsible for a specific business capability or domain. This aligns well with the principles of DDD, which emphasizes understanding and modeling the business domain to create meaningful and cohesive software solutions.&lt;/p&gt;

&lt;p&gt;Domain-Driven Design (DDD) introduces several essential components that serve as building blocks for modeling the domain data and behavior in a microservice. These components are fundamental to creating a robust and well-designed microservices architecture, next will be defined by each one of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain&lt;/strong&gt;&lt;br&gt;
Defines a specific and delimited part of the business that represents an area of knowledge with well-defined rules and concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subdomain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The subdomain is a smaller and more specialized subdivision of a broader domain, which focuses on more specific and detailed aspects of the business.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bound Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The bounded contexts are explicit boundaries that define the scope of a domain model. In microservices, each microservice typically corresponds to a bounded context, which represents a distinct domain area with its own ubiquitous language and business rules.&lt;/p&gt;

&lt;p&gt;For example, in an e-commerce application, the “User” and “Product” microservices make up their bounded context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The entities are objects that have a unique identity and remain constant over time. In the context of microservices, entities represent core business objects that have distinct attributes and behaviors.&lt;/p&gt;

&lt;p&gt;For example, in an e-commerce application, “Product” and “User” could be entities, each with its own unique identity and properties.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Value Objects&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Value objects represent concepts or attributes without their own identity. They are immutable and are used to describe the characteristics of entities.&lt;/p&gt;

&lt;p&gt;The value objects can be used to model attributes that don’t require a separate identity, for example, in the e-commerce application the Products Entity could define a value object, such as “Price” which could be made up by the value and currency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repository&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;repositories are responsible for providing access to domain objects, which are typically used for domain-specific data storage and retrieval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Services&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In short, domain services encapsulate complex domain logic that does not pertain directly to an entity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggregates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An Aggregate is a group of related objects, typically an entity and its associated value objects. They ensure consistency and transactional boundaries within the microservice.&lt;/p&gt;

&lt;p&gt;By incorporating these components defined by Domain-Driven Design, microservices can effectively model the complexities of the domain to which they belong while maintaining a clear separation of concerns.&lt;/p&gt;

&lt;p&gt;Finally, it is worth mentioning that the use of entities, value objects, aggregates, repositories, and domain services helps create a cohesive and well-organized microservice architecture that reflects the complexities of the domain that is being addressed by the functionality defined by the microservice.&lt;/p&gt;

&lt;p&gt;Domain-driven design also fosters effective communication between domain experts and developers, resulting in more successful microservices-based applications that are easy to maintain and update thanks to high coordination between different teams.&lt;/p&gt;

&lt;p&gt;When considering the implementation of a microservices-based solution, it is advisable to consider the principles defined by Domain-Driven Design (DDD). Leveraging its focus on domain modeling can significantly enhance the architecture and deepen the understanding of the business.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next readings!
&lt;/h2&gt;

&lt;p&gt;As part of the chapter series, I recommend you continue with “Chapter 4”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/josueparra2892/chapter-4-advantages-of-using-go-for-web-development-4b0k"&gt;https://dev.to/josueparra2892/chapter-4-advantages-of-using-go-for-web-development-4b0k&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Chapter 2 -Introduction to Microservices (Part 2)</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Wed, 27 Sep 2023 23:48:16 +0000</pubDate>
      <link>https://dev.to/josueparra2892/chapter-2-introduction-to-microservices-part-2-479l</link>
      <guid>https://dev.to/josueparra2892/chapter-2-introduction-to-microservices-part-2-479l</guid>
      <description>&lt;h2&gt;
  
  
  Chapter 2 -Introduction to Microservices (Part 2)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2Aj6Tj9YkJp20Gpf_ui_df0A.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2Aj6Tj9YkJp20Gpf_ui_df0A.jpeg" alt="chapter image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this chapter we continue learning about microservices, this time we going to retake all the learning from the previous chapter “&lt;a href="https://dev.to/josueparra2892/chapter-1-introduction-to-microservices-5a2c"&gt;Chapter 1 — Introduction to Microservice&lt;/a&gt;” and we are going to complete our learning with two important topics, “When to use Microservices” and “Steps to define a microservice architecture”.&lt;/p&gt;

&lt;p&gt;Let's start with this awesome travel that will help us to understand more about the wonderful world of microservices.&lt;/p&gt;

&lt;p&gt;Note: if you are not reading the previous chapter I recommend you to take a look before starting, by &lt;a href="https://dev.to/josueparra2892/chapter-1-introduction-to-microservices-5a2c"&gt;clicking here&lt;/a&gt; you can find the related article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;In this chapter, we will discuss the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When to use Microservices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Steps to define a microservice architecture&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to use Microservices
&lt;/h2&gt;

&lt;p&gt;After studying and analyzing what a microservice is, its characteristics, and the differences with other architectural styles, it is time to delve deeper into microservices. This chapter will examine common scenarios where applying a microservices architecture is appropriate in our architectural design.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, the decision to use a microservices architecture should be based on the specific requirements of our application. Here are some key points that can help identify when to apply a microservices architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;“Dealing with a complex application architecture”&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Microservices architecture is a suitable choice under several circumstances, such as “&lt;strong&gt;dealing with a complex application architecture comprising well-defined functionalities that can be effectively decoupled into independent modules”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F0%2AgM2kon-rLE5_JHfE.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F0%2AgM2kon-rLE5_JHfE.jpg" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The microservices approach enables us to leverage the benefits mentioned earlier in the previous chapter, as microservices architecture helps in service decoupling and provides a more modular, scalable, and maintainable solution.&lt;/p&gt;

&lt;p&gt;For instance, consider an e-commerce application where clear domains like products and orders exist. In such cases, dividing the application into microservices, with one dedicated to product management and another for order management, proves beneficial. Each microservice adheres to communication rules while having well-defined contexts and functionalities. This results in a more cohesive and robust system architecture.&lt;/p&gt;

&lt;p&gt;By embracing microservices architecture, the application gains flexibility and agility in development, empowers it to manage complexity more effectively, and with the right design, ensures a more resilient application, capable of handling varying demands and adapting to changing business requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  “I*&lt;em&gt;ndependent scaling&lt;/em&gt;*”
&lt;/h3&gt;

&lt;p&gt;Microservices architecture proves particularly advantageous &lt;strong&gt;“when certain parts of an application require independent scaling&lt;/strong&gt; &lt;strong&gt;to manage varying workloads effectively”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2688%2F1%2AlXoLRmVkytmg-9b1350fmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2688%2F1%2AlXoLRmVkytmg-9b1350fmg.png" alt="img1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is not always necessary to scale the entire application, this is where the implementation of microservices comes into play since on some occasions some components are used more than others. Considering the design of the application architecture, we can opt for microservices implementation. This strategic decision allows us to scale specific modules as needed, without the burden of scaling the entire application.&lt;/p&gt;

&lt;p&gt;Returning to the e-commerce example, suppose the ordering service experiences higher demand compared to the service handling user data. In such a scenario, microservices provide the ideal solution, enabling us to scale only the microservice responsible for orders without the need to scale others that don’t require it.&lt;/p&gt;

&lt;p&gt;By embracing microservices, we gain granular control over resource allocation, ensuring optimal performance, and efficient resource utilization. The ability to scale independently enhances the application’s resilience and responsiveness, making it an ideal approach for handling varying and dynamic workloads in today’s fast-paced and ever-changing digital landscape.&lt;/p&gt;

&lt;h3&gt;
  
  
  “A*&lt;em&gt;gility in development&lt;/em&gt;*”
&lt;/h3&gt;

&lt;p&gt;Microservices architecture proves to be a preferred choice &lt;strong&gt;“when agility in development and the rapid adoption of new functionalities are crucial requirements”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As highlighted earlier, the adoption of microservices significantly enhances the maintainability of our application. The independent nature of each microservice reduces complexity when implementing changes or introducing new features, ensuring that modifications in one microservice do not impact others.&lt;/p&gt;

&lt;p&gt;With microservices’ flexible and adaptable architecture, integrating changes in response to evolving requirements becomes more streamlined and efficient. This adaptability allows development teams to respond quickly to business needs, accelerating time-to-market for new functionalities and features.&lt;/p&gt;

&lt;p&gt;By embracing microservices, organizations gain a competitive edge, enabling them to stay nimble in an ever-changing market landscape. The modular and independent nature of microservices empowers development teams to be more responsive, innovative, and collaborative, ultimately driving business success in today’s fast-paced digital ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  “R*&lt;em&gt;educe the complexity&lt;/em&gt;*”
&lt;/h3&gt;

&lt;p&gt;Microservices architecture is an ideal choice “&lt;strong&gt;when&lt;/strong&gt; &lt;strong&gt;aiming to reduce the complexity of an application”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2ADRFojnXBC3ahtIA0" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2ADRFojnXBC3ahtIA0" alt="img2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By its very nature, microservices offer a lightweight and modular structure for designing applications. This architectural approach not only eases the burden of maintenance but also simplifies testing and enhances software quality. Treating each microservice independently allows for focused development and evolution, ensuring that changes can be made more efficiently and tailored to specific needs.&lt;/p&gt;

&lt;p&gt;The clear separation of functionalities in microservices results in a more manageable and maintainable system, making it easier to pinpoint and address issues when they arise. This, in turn, fosters a more agile and responsive development process, empowering teams to deliver high-quality software with fewer complexities.&lt;/p&gt;

&lt;p&gt;By reducing the application’s intricacies, development teams can focus on delivering value and enhancing the user experience, while also ensuring the long-term sustainability and maintainability of the software.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;“Multiple development teams”&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Microservices architecture is a highly beneficial choice &lt;strong&gt;“when multiple development teams collaborate on different areas of an application and seek independence and autonomy in their responsibilities”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2Ak618mDMsgD_prS5E.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2Ak618mDMsgD_prS5E.png" alt="img3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For large-scale applications comprising multiple components, implementing a microservices-based solution proves to be an effective strategy. Assigning each microservice to a specific team allows for focused maintenance and development efforts.&lt;/p&gt;

&lt;p&gt;This clear separation of responsibilities reduces inter-team dependencies, streamlining the process of implementing changes. Each team becomes responsible for deploying updates to their designated microservice, promoting a more agile and efficient development workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  “N*&lt;em&gt;eed to utilize different technologies&lt;/em&gt;*”
&lt;/h3&gt;

&lt;p&gt;Microservices architecture is the ideal choice &lt;strong&gt;“when there is a need to utilize different technologies and programming languages within an application”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AwiKtcXH9smj2hVoKGkxmjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AwiKtcXH9smj2hVoKGkxmjg.png" alt="img4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During the architectural design phase, we may identify specific functionalities that benefit from the capabilities offered by certain programming languages or databases. Microservices present an elegant solution to this challenge by enabling us to divide the application into distinct domains, allowing each microservice to be implemented using the most suitable technology for its specific requirements.&lt;/p&gt;

&lt;p&gt;This approach not only promotes flexibility in development but also mitigates technological lock-ins. With microservices, teams can work with their preferred technologies, enabling them to innovate and optimize their respective microservices without being limited by the overall application’s technology stack.&lt;/p&gt;

&lt;p&gt;embracing microservices architecture facilitates a harmonious integration of different technologies and programming languages. This freedom of technology selection enhances development efficiency and empowers teams to leverage the best tools for each microservice’s unique requirements, ultimately delivering a more resilient, maintainable, and future-proof application.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;“Expected to experience exponential growth”&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Microservices architecture is indispensable &lt;strong&gt;“when dealing with an application expected to experience exponential growth”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AV_pi0P-KzkSNyDk3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AV_pi0P-KzkSNyDk3.png" alt="img5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When an application is expected to have a high demand of usage, the implementation of microservices is vital since, as mentioned in their characteristics, they offer a high level of scalability and less complexity for their maintenance.&lt;/p&gt;

&lt;p&gt;A microservices architecture allows different parts of the application to be developed and deployed independently, facilitating its evolution and growth.&lt;/p&gt;

&lt;p&gt;the implementation of microservices architecture is essential to meet the challenges posed by the exponential growth of an application. Their scalable and maintainable nature not only ensures smooth operation during periods of high demand but also lays a robust foundation for future expansion and innovation.&lt;/p&gt;

&lt;h3&gt;
  
  
  “F*&lt;em&gt;ault tolerance&lt;/em&gt;*”
&lt;/h3&gt;

&lt;p&gt;Microservices architecture is the optimal choice &lt;strong&gt;“when greater fault tolerance is a priority”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2ApU5r9rGhnGjlkl4Z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2ApU5r9rGhnGjlkl4Z.png" alt="img6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For applications that require high availability, microservices offer significant advantages in mitigating failures that may occur between different microservices. Their modular nature facilitates fault detection and resolution, ensuring that errors are isolated and swiftly addressed. Being more tolerant to faults, the microservices architecture helps the resilience of the system as it provides more stable performance.&lt;/p&gt;

&lt;p&gt;By embracing microservices, the architecture inherently promotes fault tolerance, resulting in a more resilient system. The decentralized structure of microservices ensures that failures in one service do not cascade to impact the entire application. This isolation of faults allows other services to continue functioning without disruption.&lt;/p&gt;

&lt;p&gt;Those use cases help to clarify the usability of the microservices and help to evaluate the applications and evaluate if the implementation of microservices architecture is the appropriate solution or if we should use a simpler architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Steps to define a microservice architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This topic will explore the essential factors that aid in defining the required microservices for an application. These points are closely related to the characteristics of microservices and align with the opportunities discussed earlier when considering the adoption of microservices.&lt;/p&gt;

&lt;p&gt;It is crucial to emphasize that the points mentioned here are general and apply to a wide range of microservices solutions. However, it is essential to consider that each system may possess specific characteristics that necessitate careful analysis on a case-by-case basis.&lt;/p&gt;

&lt;p&gt;The following is a list of the steps that could be followed when defining a microservice-based architecture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A-W8pDDBSfKcyphcjHGpeNQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A-W8pDDBSfKcyphcjHGpeNQ.png" alt="img7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Domain Analysis&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is the first step and one of the most important, a good definition of the domain is crucial for the architecture decision. In this step, a good understanding of the different domains and responsibilities of the application is the base for identifying which functionalities can be treated as independent microservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Decoupling&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2004%2F1%2A6RLdDQGy_JJxKv4kjyyK4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2004%2F1%2A6RLdDQGy_JJxKv4kjyyK4w.png" alt="img8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the domains are clearly defined, and all potential functionalities that can be transformed into microservices are identified, the next step is decoupling. Adhering to the principles of microservices architecture offers advantages in designing each microservice with a specific responsibility and ensuring its independence from other services. This decoupling enhances the system’s evolution and maintainability.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Granularity&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3344%2F1%2AIg_Djz1BfEJuFA8rienxOA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3344%2F1%2AIg_Djz1BfEJuFA8rienxOA.png" alt="img9"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This point may seem simple, but it is of utmost importance. When defining microservices, careful consideration should be given to their appropriate size. Avoiding microservices that are either too small or too large is vital to ensure an optimal architectural design.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Well-Defined Communication Interfaces&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2004%2F1%2ATjZZf6S7Lme_hq7cP37L_A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2004%2F1%2ATjZZf6S7Lme_hq7cP37L_A.png" alt="img10"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In designing microservices one of the challenges is communication. Is needed to ensure effective communication between microservices by making informed decisions on how they will interact with each other like synchronous or asynchronous communication. On the other hand, Clearly define well-defined interfaces for each microservice to facilitate seamless communication within the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scalability and Fault Tolerance&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When designing microservices, it is vital to prioritize scalability and fault tolerance. Each microservice should be capable of independent scalability, enabling it to handle varying workloads effectively. Implementing fault tolerance techniques ensures system availability, enhancing the overall robustness of the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Independent Implementation and Deployment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Strategies must be devised to facilitate the independent deployment and updating of each microservice. These approaches should adhere to the key principle that mentions “&lt;strong&gt;&lt;em&gt;changes in one microservice should not impact others&lt;/em&gt;&lt;/strong&gt;”.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Observability&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Establishing observability tools for each microservice to quickly detect and fix anomalies, as well as monitoring the performance and efficiency of each microservice and optimizing them when necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Security&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2628%2F1%2AucJ-K4VBijhS36ygyMz0EQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2628%2F1%2AucJ-K4VBijhS36ygyMz0EQ.png" alt="img11"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When defining microservices, ensuring robust security measures is of paramount importance, especially for communication between each service. Implementing measures like “encryption,” “authentication,” and “authorization” is essential to safeguard communication and data transfer between microservices. Additionally, proper access control should be enforced to ensure appropriate utilization of the resources provided by the microservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Team and Culture&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2560%2F0%2AHEwgAUpqCJXQl_wN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2560%2F0%2AHEwgAUpqCJXQl_wN.png" alt="img12"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fully harness the benefits of the microservices architecture, it is advisable to form specialized and multidisciplinary teams for the development and maintenance of each microservice. This practice helps to cultivate a collaborative and agile culture to ensure the seamless implementation and success of microservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Integration Testing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Conducting thorough integration tests on each microservice is an essential requirement to ensure seamless functionality and successful communication between them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Documentation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Creating comprehensive and up-to-date documentation for each microservice is crucial to ensure that other teams can easily comprehend and utilize them effectively. This documentation should be accessible, well-structured, and regularly maintained to support seamless collaboration and understanding among teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Version Management&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AV2YGTfpAmMhL8d7n4B2ckQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AV2YGTfpAmMhL8d7n4B2ckQ.png" alt="img13"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is essential to manage the versions of each microservice to ensure adequate and documented control of the updates and changes made. Keeping track of releases will allow efficient development management and make it easier to identify significant changes to the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Continuous Reassessment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;It is crucial to be willing to re-evaluate the microservices architecture based on evolving requirements and technologies. This ensures that the choice of microservices remains the best option for the project at hand. The adaptability and flexibility to adjust the architecture according to the changing needs of the project are essential to maintain an optimal and efficient system over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Embracing microservices architecture is an intelligent choice for businesses seeking to build robust, scalable, and future-proof applications in the dynamic landscape of modern software development.&lt;/p&gt;

&lt;p&gt;In conclusion, by carefully following these steps, considering the unique characteristics of microservices, and evaluating the use cases discussed in previous topics, we can craft a robust and efficient microservices architecture that caters to the evolving requirements of our application and ensures its sustained success in the long run.&lt;/p&gt;




&lt;p&gt;Next reading:&lt;br&gt;
Chapter 3: &lt;a href="https://dev.to/josueparra2892/chapter-3-domain-driven-design-and-microservices-371b"&gt;https://dev.to/josueparra2892/chapter-3-domain-driven-design-and-microservices-371b&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Chapter 1 — Introduction to Microservices</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Wed, 27 Sep 2023 23:44:37 +0000</pubDate>
      <link>https://dev.to/josueparra2892/chapter-1-introduction-to-microservices-5a2c</link>
      <guid>https://dev.to/josueparra2892/chapter-1-introduction-to-microservices-5a2c</guid>
      <description>&lt;h2&gt;
  
  
  Chapter 1 — Introduction to Microservices
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2A5eH-mrnxmxnyEwF49UzQzA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2048%2F1%2A5eH-mrnxmxnyEwF49UzQzA.jpeg" alt="cahpter image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;In this chapter, we will discuss the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Defining a microservice&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;History of Microservices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Key characteristics of microservices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Benefits and advantages of using microservices in software development&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Challenges related to microservices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comparison with other architectural styles&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monolithic Architecture&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Distributed Monolith Architecture&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Best practices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microservices on real-world scenarios&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Defining a Microservice&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To define what a microservice is, I would like to mention one of the explanations given by &lt;strong&gt;&lt;em&gt;Martin Fowler&lt;/em&gt;&lt;/strong&gt;, 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2ANj2dYGlVUrqx3UgG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2ANj2dYGlVUrqx3UgG" alt="***Figure 1.1**: Microservices example for an e-commerce application. The Web Application represents one of the possible clients.*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;History of microservices&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key characteristics of microservices&lt;/strong&gt;.
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2ACWw7S3HnSWDTEu8B" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2ACWw7S3HnSWDTEu8B" alt="***Figure 1.2**: Microservices characteristics*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Independent Components&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3016%2F0%2AETKu3WDCvdxhGm5v" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3016%2F0%2AETKu3WDCvdxhGm5v" alt="***Figure 1.3**: Each request is done to the specific microservice that ensures the domain and functionality independence.*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Granularity&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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”.&lt;/p&gt;

&lt;p&gt;Figure 1.4 shows microservices granularity. Each one defines its functionality scope and its storage based on its functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2656%2F0%2AspBKtjH1FDPZ1BhP" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2656%2F0%2AspBKtjH1FDPZ1BhP" alt="***Figure 1.4**: Microservices Granularity representation.*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Decentralized Data Management&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3076%2F0%2AA5bJ_n9Lzm9dGiWe" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3076%2F0%2AA5bJ_n9Lzm9dGiWe" alt="***Figure 1.5**: Centralized Storage vs Dedicated Storage*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;strong&gt;Martin Fowler&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Lightweight communication&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2220%2F0%2AiP9xQUV8dOSFSbx-" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2220%2F0%2AiP9xQUV8dOSFSbx-" alt="***Figure 1.6**: Synchronous and Asynchronous microservice communication.*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Products not Projects&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scalability and failure tolerance&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2828%2F0%2AX_Am7eUkvf5dil6f" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2828%2F0%2AX_Am7eUkvf5dil6f" alt="***Figure 1.7**: Scaling a microservice-based application implementing a load balancer.*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Maintainability and Team Distribution&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits and advantages of using microservices in software development&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The following list shows the main benefits and advantages offered by the microservices architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**Independence and Autonomy&lt;br&gt;
**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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Organizational Scalability&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Technological Flexibility&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maintainability&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuous Deployment&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resilience and Fault Tolerance&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved User Experience&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Challenges related to microservices&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The following are some of the challenges presented in a microservices implementation, as well as the recommendation to mitigate the impact related to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Managing Complexity&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;To tackle this challenge, the following recommendations are often suggested:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Proper Modularity for the Microservice&lt;/strong&gt; &lt;br&gt;
This involves ensuring that each microservice has a well-defined specific responsibility and is as independent as possible from other microservices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dependency Management&lt;/strong&gt;&lt;br&gt;
This refers to identifying dependencies with other services to establish appropriate communication between them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;&lt;br&gt;
It is advisable to implement monitoring tools for our microservices to help detect potential issues in each of them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuous Integration and Continuous Delivery&lt;/strong&gt;&lt;br&gt;
Applying techniques of continuous integration and deployment helps reduce the complexity of our microservices.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Communication between Services&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Some techniques implemented to mitigate this challenge include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implementing well-defined interfaces&lt;/strong&gt;. This point implies defining contracts that will be used for communication between microservices by implementing APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Using communication protocols&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fault tolerance&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integration testing and monitoring&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Data Consistency and Synchronization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Some of the techniques to address this challenge are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Eventual Consistency&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Messaging Patterns and Events&lt;/strong&gt;. By implementing events and asynchronous messaging in our microservices, we can ensure efficient propagation of changes throughout our service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Distributed Transactions&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Domain Boundaries&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Monitoring and Issue Resolution&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Security&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Some of the recommended measures to address this challenge are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use of authentication and authorization systems in the communication of our microservices&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implementation of audit and registration of events&lt;/strong&gt;. Keeping a record of the processes made by each of the microservices is beneficial when detecting anomalies in our system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Protection of data in transit&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Multiple Microservices Multiple Configurations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Some of the recommendations are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centralized configuration storage&lt;/strong&gt;. For these cases, it can be a configuration repository or some configuration management service that allows us to obtain the values quickly and safely.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Environment-based configuration&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automated deployments and updates&lt;/strong&gt;. 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.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Culture and Organization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Comparison with other architectural styles&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Monolithic Architecture&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2AEUvrOQxfGc7YtnU7" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F0%2AEUvrOQxfGc7YtnU7" alt="***Figure 1.8**: Monolithic Architecture representation.*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;**Differences with microservices&lt;br&gt;
**Several key differences between microservices architecture and monolithic architecture that could help us to evaluate the use of microservices in our application, differences are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Coupling&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability and Fault Tolerance&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Independent Deployment&lt;br&gt;
**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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Maintenance&lt;br&gt;
**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. &lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Diverse Technologies and Languages&lt;br&gt;
**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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Storage management&lt;br&gt;
**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. &lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Granularity&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Distributed Monolith Architecture&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Best practices&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“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”.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Define domains for each microservice&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Communication via well-defined interfaces&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;service decoupling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Independent scalability&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fault tolerance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;version management&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;monitoring and recording&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automation and CI/CD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;clear documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integration testing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;collaborative development&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;continuous reassessment&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;**Microservices on real-world scenarios&lt;br&gt;
**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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Netflix&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Uber&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Airbnb&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Amazon&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Twitter&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The important points to remember are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Microservices-based architecture aims to decompose monolithic applications into small, independent components, each with a clearly defined functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In studying the key characteristics of microservices, we have observed their emphasis on high cohesion and loose coupling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microservices provide excellent scalability and ease of maintenance, making them fundamental attributes for implementation in modern and highly dynamic environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When considering the adoption of a microservices architecture, it is crucial to take into account the challenges and difficulties that we have already analyzed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;




&lt;p&gt;Next reading:&lt;br&gt;
Chapter 2. &lt;a href="https://dev.to/josueparra2892/chapter-2-introduction-to-microservices-part-2-479l"&gt;https://dev.to/josueparra2892/chapter-2-introduction-to-microservices-part-2-479l&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Microservice architecture with Go</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Wed, 27 Sep 2023 19:13:34 +0000</pubDate>
      <link>https://dev.to/josueparra2892/microservice-architecture-with-go-e6i</link>
      <guid>https://dev.to/josueparra2892/microservice-architecture-with-go-e6i</guid>
      <description>&lt;p&gt;I'd like to share with you this awesome series of articles related to Microservices architecture implementing Golang programming language&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/dev-genius/chapter-1-6379b9d66ff3"&gt;https://medium.com/dev-genius/chapter-1-6379b9d66ff3&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Elastic Compute Cloud (EC2)</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Wed, 28 Jun 2023 04:45:42 +0000</pubDate>
      <link>https://dev.to/josueparra2892/configure-based-on-the-following-images-1i6</link>
      <guid>https://dev.to/josueparra2892/configure-based-on-the-following-images-1i6</guid>
      <description>&lt;h2&gt;
  
  
  Tutorial - Elastic Compute Cloud (EC2)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating EC2 instances from zero
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zf2S9Edk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AI4-c3kEa6MQVxvYL.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zf2S9Edk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AI4-c3kEa6MQVxvYL.png" alt="" width="740" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is EC2?
&lt;/h3&gt;

&lt;p&gt;In a few words EC2 or Amazon Elastic Compute Cloud is a virtual machine that contains an AMI (image with a selected OS with all the needed configurations) with EC2 you could create instances related to specific tasks or resources, for example, you could easily configure an EC2 with an AMI for data processing, for GPU computing or simple ones to just run web applications.&lt;/p&gt;

&lt;p&gt;EC2 could be seen as a virtual server where you are able to run your applications.&lt;/p&gt;

&lt;p&gt;In its features we could find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Global infrastructure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pay as you use it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Networking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optimization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintenance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to learn more about the specifications you can visit the official page of AWS EC2 &lt;a href="https://aws.amazon.com/ec2/features/"&gt;https://aws.amazon.com/ec2/features/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating an EC2 instance
&lt;/h2&gt;

&lt;p&gt;Cool, now that we know a bit about what this service is, the next step is to start with our practical example.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Steps to follow:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Configure VPC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure a public subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure the internet gateway.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the EC2 instance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Configure a VPC&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A VPC is a private network that we have in our cloud, is similar to having a physical network like you could do in your office to connect your servers but now at the logic level in the cloud.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let us start.&lt;/p&gt;

&lt;p&gt;The first thing is to go to our AWS console and in the services choose VPC to go to the VPC dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VWwzRAAJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AjLtXV8-BbiOf5WeS.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VWwzRAAJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AjLtXV8-BbiOf5WeS.png" alt="" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There we going to see the option create VPC Click it to start creating a new one.&lt;/p&gt;

&lt;p&gt;It will display a form like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NV5WlKaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3380/1%2Ajq-flaJUkLVDqJfZlgm_Cg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NV5WlKaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3380/1%2Ajq-flaJUkLVDqJfZlgm_Cg.png" alt="" width="800" height="885"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will share with you the configurations used to create the new one:&lt;/p&gt;

&lt;p&gt;First part:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Give a name, example VPCMediumTutorial&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Give the CIDR range. In this case, we can use 10.0.0.0/16&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The option for IPv6. Choose No IPv6 CIDR block&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tenancy. Keep it with the default value&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hi7Hx0bY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2A2OEXXlO3EVIqwZn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hi7Hx0bY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2A2OEXXlO3EVIqwZn8.png" alt="" width="730" height="852"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down to the following section:&lt;/p&gt;

&lt;p&gt;The following options should be enabled:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Enable DNS hostnames&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable DNS resolution&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In tags, you can define a tag to identify the VPC by example the env for deployments, etc. In this case, I used medium_tutorial as a value&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2fAVSWuA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AquKlhApn0UqMMzuu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2fAVSWuA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AquKlhApn0UqMMzuu.png" alt="" width="757" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then click on create , a message will be displayed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n0rEOWSD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2598/0%2ALahc3ijDXleQ0imI.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n0rEOWSD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2598/0%2ALahc3ijDXleQ0imI.png" alt="" width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can see the VPC details in Your VPCs panel:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e9wJaFqK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AydHhVcKx-4mCiTHb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e9wJaFqK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AydHhVcKx-4mCiTHb.png" alt="" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose the created one and a page like this will be shown&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I4ZXeYrK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AHW7y2BpIT7Gyi_PF.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I4ZXeYrK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AHW7y2BpIT7Gyi_PF.png" alt="" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure the public subnet&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is a public subnet?, A public subnet is a subnet within a VPC that has an Internet Gateway route and whose instances have a publicly accessible IP address from the Internet. Public subnets are commonly used to host internet-facing resources, such as web servers or public databases.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once we have created our VPC is time to add a public subnet, to do that you can take base the following steps:&lt;/p&gt;

&lt;p&gt;In the left pane choose subnets that will take you to the following page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oJsTVTTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AbOyBJFAI2hwgu754.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oJsTVTTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AbOyBJFAI2hwgu754.png" alt="" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on create, then Choose the VPC that we created in the previous section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hrN5qjLF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2720/0%2ApiwZG3TfAxZl3pQe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hrN5qjLF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2720/0%2ApiwZG3TfAxZl3pQe.png" alt="" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then start to add the configurations for the public subnet, like is shown in the image below:&lt;/p&gt;

&lt;p&gt;As you can see we choose the same availability zone of our VPC and for the CIDR we will define (for this tutorial) 10.0.0.0/24.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8JNU5rGK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2414/0%2AFSC_rP1swdydS1au.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8JNU5rGK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2414/0%2AFSC_rP1swdydS1au.png" alt="" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on create. One success message will be displayed and then you going to be able to see the public subnet in the table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--69CR_Yc_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5948/1%2AxaJWGuCB2QJByNScwHgg9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--69CR_Yc_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5948/1%2AxaJWGuCB2QJByNScwHgg9w.png" alt="" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is for this step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure the internet gateway&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The AWS Internet Gateway is an Amazon Web Services (AWS) service that provides a secure and scalable connection between a Virtual Private Cloud (VPC) and the public Internet. Essentially, the Internet Gateway is a virtual gateway that allows bidirectional network traffic between the resources in a VPC and the Internet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the left pane choose internet gateways and then provide a name and make click on create.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vtuKPtBs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AbxpJCPaDfeoE7ilB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vtuKPtBs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AbxpJCPaDfeoE7ilB.png" alt="" width="316" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ovZUlbPk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2606/0%2AOhcTrVzkAvE8KbD2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ovZUlbPk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2606/0%2AOhcTrVzkAvE8KbD2.png" alt="" width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OYGnRScl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2Ae75t3rpa7r0fm56Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OYGnRScl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2Ae75t3rpa7r0fm56Q.png" alt="" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to attach it to our created VPC. To do that we need to go to actions and then attach to VPC, as is shown in the images below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pd1Qa3sF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2A1FAryDJ5hDweIbNm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pd1Qa3sF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2A1FAryDJ5hDweIbNm.png" alt="" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eLLyGGDG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2ALKVDXzyxJQQRwLv1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eLLyGGDG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2ALKVDXzyxJQQRwLv1.png" alt="" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you attached the internet gateway to the created VPC we need to go to the subnet and make a couple of configurations more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jtasH5Zt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5856/1%2A6HE7_OX_djpovKdg8eKxGg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jtasH5Zt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5856/1%2A6HE7_OX_djpovKdg8eKxGg.png" alt="" width="800" height="139"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the subnets table, choose the one that we created, select the details section make click on the route table:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OlXbm4n_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AAtsdWXiYZDqZS2ub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OlXbm4n_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AAtsdWXiYZDqZS2ub.png" alt="" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That action will take you to the following view where you should click on create a route table:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nd6jUNKG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2ASUpLkGM-k44ZWkR6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nd6jUNKG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2ASUpLkGM-k44ZWkR6.png" alt="" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;add the following and click on create:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ebVm8Ktn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2570/0%2Agx6IcJCbkftVhtpB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ebVm8Ktn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2570/0%2Agx6IcJCbkftVhtpB.png" alt="" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O19-hOB9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2A_emDeuKz2v3HNMoy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O19-hOB9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2A_emDeuKz2v3HNMoy.png" alt="" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to add the new route table to our public subnet. To do that go to Edit subnet association and edit it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RQA-nclE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AP10Wtp18nzf0YDQv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RQA-nclE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AP10Wtp18nzf0YDQv.png" alt="" width="800" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_fqAbVK4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AyqtiNcRRE2T4JVfM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_fqAbVK4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AyqtiNcRRE2T4JVfM.png" alt="" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the same view choose routes, we need to add a new internet routing&lt;/p&gt;

&lt;p&gt;Click on edit routes and add the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u289PRbS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2APIDdFv80poHUA9aV.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u289PRbS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2APIDdFv80poHUA9aV.png" alt="" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_hi6roGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2APkg8lqRZCtvctKSg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_hi6roGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2APkg8lqRZCtvctKSg.png" alt="" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the EC2 instance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Navigate to EC2 service dashboard&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_l1PYtob--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AAXLalrroPIXm1rGw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_l1PYtob--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2AAXLalrroPIXm1rGw.png" alt="" width="800" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to Instances in the left panel, It will take you to the instances view Once there click on the launch instance option:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g7e5enne--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5972/1%2A6g59bypSz8RjiZgHqlJmyg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g7e5enne--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5972/1%2A6g59bypSz8RjiZgHqlJmyg.png" alt="" width="800" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A new view is loaded, here is where we going to configure our EC2 instance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Give a name, medium-tutorial for example.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the AMI, in this case, we will use Amazon Linux.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5ZnQuZ-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2132/0%2A--Lr6nWriRx5G3tf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5ZnQuZ-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2132/0%2A--Lr6nWriRx5G3tf.png" alt="" width="800" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Network settings&lt;/strong&gt;
Click on edit in order to add our configurations based on the VPC with internet access. Here we going to choose the one that we created.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R8UmXAvO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2202/0%2AkBGg281h_B4e0hpU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R8UmXAvO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2202/0%2AkBGg281h_B4e0hpU.png" alt="" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Create a new security group&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gONt21XJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2124/0%2Abv2kaaMNj0jHDso0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gONt21XJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2124/0%2Abv2kaaMNj0jHDso0.png" alt="" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Add the security rules&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can take as an example the image below.&lt;/p&gt;

&lt;p&gt;In this case, we going to add the configurations needed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ssh connection based on your IP address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HTTP connection from anywhere 0.0.0.0/0 ::/0&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KisWEO-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/NaN/1%2AHsofcMSoXHpGD_xKUyOhow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KisWEO-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/NaN/1%2AHsofcMSoXHpGD_xKUyOhow.png" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;**Create a key pair
**Use the name medium_tutorial and click create. It will download a .pem file that we going to need to connect by ssh.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gjXc8_c8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/NaN/1%2AGOBjkoz9nAVDksmdC424Sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gjXc8_c8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/NaN/1%2AGOBjkoz9nAVDksmdC424Sw.png" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Add user data on advanced details&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here we going to add the instructions to create a simple server that shows the instance IP, to do that you need to go to advanced details and include the lines below in the user data field&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
# Utiliza esto para tus datos de usuario
# Instala httpd (Version: Linux 2)
sudo su
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "&amp;lt;h1&amp;gt;Hello from:  $(hostname -f)&amp;lt;/h1&amp;gt;" &amp;gt; /var/www/html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yaBMkE_U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3120/1%2AIeUC-F3PJ1xj2D-Outf4fw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yaBMkE_U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3120/1%2AIeUC-F3PJ1xj2D-Outf4fw.png" alt="" width="800" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---TAcQDus--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2396/1%2AEa3VYnTjQYCQ-yyxNvZDig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---TAcQDus--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2396/1%2AEa3VYnTjQYCQ-yyxNvZDig.png" alt="" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ready, now just make click on create.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u2AyOtJK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2A3rDGLP06wvD0MDVg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u2AyOtJK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2800/0%2A3rDGLP06wvD0MDVg.png" alt="" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now to these the instance you can click over the instance Id, then copy and paste the Public IPv4 DNS in a browser and you will be able to see something like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wUtxUyr5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2500/1%2ALCLPNBxyP8MPOYWdJN-I8A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wUtxUyr5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2500/1%2ALCLPNBxyP8MPOYWdJN-I8A.png" alt="" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bonus!!!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Qn8klVoy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2520/1%2Afd6NF6dyE4VxZMAdcR55AQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Qn8klVoy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2520/1%2Afd6NF6dyE4VxZMAdcR55AQ.png" alt="" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to configure the VPC, Subnet, and internet gateway in an easier way?&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Go to VPC dashboard&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jLoRsy-F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4376/1%2Awo7YA2yhZKeArzwjvV52EQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jLoRsy-F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4376/1%2Awo7YA2yhZKeArzwjvV52EQ.png" alt="" width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Click on create VPC&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;**Configure based on the following images&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PRc5BIIe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2188/1%2AhhDw4UVWYle9ykRBbs_7Ag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PRc5BIIe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2188/1%2AhhDw4UVWYle9ykRBbs_7Ag.png" alt="" width="800" height="1242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1fYU9zwB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ABZRmq3fLzqBr8SgfAduzvA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1fYU9zwB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ABZRmq3fLzqBr8SgfAduzvA.png" alt="" width="800" height="1117"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see we are adding all the needed basic configurations to generate the VPC, our public subnet, and the internet gateway.&lt;/p&gt;

&lt;p&gt;In addition, you can see the configuration in the diagram that is generated based on your selections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--009xpQmb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5916/1%2APakvSg-_yxAuhPDq43cm8A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--009xpQmb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5916/1%2APakvSg-_yxAuhPDq43cm8A.png" alt="" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After adding those configurations just click on create and ready your VPC is ready to use.&lt;/p&gt;

&lt;p&gt;You can use this option to create the EC2 instance and it should work, and as you can see is easier that the first option that we see in this tutorial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ah9B5otq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5200/0%2A5XOjRx1VZ021iJRx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ah9B5otq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5200/0%2A5XOjRx1VZ021iJRx.jpg" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ec2</category>
      <category>cloud</category>
    </item>
    <item>
      <title>AWS Elastic Load Balancer and Auto Scaling Groups</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Wed, 28 Jun 2023 04:42:29 +0000</pubDate>
      <link>https://dev.to/josueparra2892/aws-elastic-load-balancer-and-auto-scaling-groups-3hkm</link>
      <guid>https://dev.to/josueparra2892/aws-elastic-load-balancer-and-auto-scaling-groups-3hkm</guid>
      <description>&lt;h2&gt;
  
  
  AWS Elastic Load Balancer and Auto Scaling Groups
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Amazon Web Services tutorial — ELB and ASG
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7SDeoMkQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3748/1%2ACnUYtKWpanSAszLmjbKTRw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7SDeoMkQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3748/1%2ACnUYtKWpanSAszLmjbKTRw.png" alt="" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial, we will review two essential AWS services that help us with our application scalability, ELB (elastic load balancer) and ASG (Auto scaling groups).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you are new with the scaling concept I recommend you take a look at this article where I talk about scalability — &lt;a href="https://medium.com/dev-genius/vertical-scaling-vs-horizontal-scaling-cfad0ff2d7bf"&gt;https://medium.com/dev-genius/vertical-scaling-vs-horizontal-scaling-cfad0ff2d7bf&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;First, let us talk about what a load balancer is.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“A load balancer is a device or software that distributes network traffic among multiple servers or computing resources to improve the performance, scalability, availability, and reliability of an online service or application”.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A load balancer acts as an intermediary between clients and servers and uses routing algorithms to distribute network traffic across multiple servers or application instances, depending on the number of requests that the service is receiving.&lt;/p&gt;

&lt;p&gt;Imagine the following scenario. You have an e-commerce application and you detect the dates with more traffic (could be black Friday for example), then you and your team decide to generate multiples instances of your application in different servers, and the next step, how are we going to work with those deployments as one? the answer is, implementing a load balancer to distribute the request along the different instances.&lt;/p&gt;

&lt;p&gt;Cool, now we understand what is a load balancer and when we could implement it, but how we can implement a load balancer?, there are a lot of services, frameworks, and approaches to work with a load balancer, for example, if we are using a cloud like AWS we are able to use a service named ELB which is one that we going to use in this tutorial.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is ELB?
&lt;/h3&gt;

&lt;p&gt;ELB stands for “Elastic Load Balancer”, which is an AWS cloud service that helps us to implement a load balancer in our solutions. Elastic Load Balancing (ELB) automatically distributes incoming application traffic across multiple targets and virtual appliances in one or more Availability Zones.&lt;/p&gt;

&lt;p&gt;AWS offers three different types of load balancers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Application Load Balancer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gateway Load Balancer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network Load Balancer&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this tutorial, we going to focus on the Application load balancer option. In the following image you can see how it works from a general perspective:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Your client makes a request to your application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The listeners in your load balancer receive requests matching the protocol and port that you configure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The receiving listener evaluates the incoming request against the rules you specify, and if applicable, routes the request to the appropriate target group. You can use an HTTPS listener to offload the work of TLS encryption and decryption to your load balancer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Healthy targets in one or more target groups receive traffic based on the load-balancing algorithm, and the routing rules you specify in the listener.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Gy3KbhO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AbqmbPwys3LN4i3EHpDZ8Bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Gy3KbhO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AbqmbPwys3LN4i3EHpDZ8Bg.png" alt="" width="686" height="698"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hands-on!… and let start with an example to learn how to use ELB&lt;/p&gt;

&lt;p&gt;For this tutorial we are going to need:&lt;/p&gt;

&lt;p&gt;Two EC2 instances (configured with internet access).&lt;br&gt;
 &lt;em&gt;— If you are new and want to learn how to make this step, you can follow this tutorial &lt;a href="https://medium.com/@josueparra2892/tutorial-elastic-compute-cloud-ec2-1d20dd8d64a1"&gt;https://medium.com/@josueparra2892/tutorial-elastic-compute-cloud-ec2-1d20dd8d64a1&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure an ELB to distribute the traffic between the EC2 instances.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Creating the EC2 instances&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At the time to create your instance, you should use the following configurations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The instance type could be t2.micr .&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AMI: Amazon Linux&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your instance should have internet access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As part of the Advanced details in the field of user data . You need to use add the following lines. &lt;br&gt;
The configuration above will help us to create a basic service that displays the instance IP address.&lt;/p&gt;
&lt;h1&gt;
  
  
  !/bin/bash
&lt;/h1&gt;
&lt;h1&gt;
  
  
  Utiliza esto para tus datos de usuario
&lt;/h1&gt;
&lt;h1&gt;
  
  
  Instala httpd (Version: Linux 2)
&lt;/h1&gt;

&lt;p&gt;sudo su&lt;br&gt;
yum update -y&lt;br&gt;
yum install -y httpd&lt;br&gt;
systemctl start httpd&lt;br&gt;
systemctl enable httpd&lt;br&gt;
echo "&lt;/p&gt;
&lt;h1&gt;Hello from $(hostname -f)&lt;/h1&gt;" &amp;gt; /var/www/html/index.html&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: you should create 2 instances for this tutorial, but in a real-world application you can define as much as you need.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P3odY-OB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5928/1%2AAGXnIjNgVWpJyk_H-p-reg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P3odY-OB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/5928/1%2AAGXnIjNgVWpJyk_H-p-reg.png" alt="" width="800" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instance 1:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NyHMfKnW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2680/1%2AFrqYQIGolbjrALgwfy7wAg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NyHMfKnW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2680/1%2AFrqYQIGolbjrALgwfy7wAg.png" alt="" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instance 2:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MQUusgpC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2468/1%2AZinPoxo1Fw_HRQXJO1GsOg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MQUusgpC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2468/1%2AZinPoxo1Fw_HRQXJO1GsOg.png" alt="" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Important considerations at a time to build our ELB
&lt;/h3&gt;

&lt;p&gt;The following points are very important to make the ELB works correctly&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The VPC should be the same in your instances and in your ELB configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need at least 2 availability zones, each one with its subnets with internet access&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your instances should be configured in the same VPC&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configure ELB (Elastic Load Balancing)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jzaotWBx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AOvn05YAi3fV2_f2C.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jzaotWBx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AOvn05YAi3fV2_f2C.png" alt="" width="350" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To do this step you first have to navigate to the “load balancing” menu in the left panel inside of the EC2 dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cq6jeD3B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2A3xk0iGeK1KxzPa-GzVQgxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cq6jeD3B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2A3xk0iGeK1KxzPa-GzVQgxw.png" alt="" width="486" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then make click on “load Balancer”, it going to take you to the following screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MDmuBkzr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/6104/1%2AqpQXP0WWQdcACjNGqTeuLg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MDmuBkzr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/6104/1%2AqpQXP0WWQdcACjNGqTeuLg.png" alt="" width="800" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once there you should click on create “load balancer”, then you going to see something like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b62xWJ1F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4256/1%2Aw2jNPwyjkoVDpT7VIV42Dw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b62xWJ1F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4256/1%2Aw2jNPwyjkoVDpT7VIV42Dw.png" alt="" width="800" height="661"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I mentioned before we going to review in this tutorial the option of “Application Load Balancer”, it will help us to distribute the request using the ELB between the EC2 instances.&lt;/p&gt;

&lt;p&gt;Then you need to click on create of the first option “Application Load Balancer”.&lt;/p&gt;

&lt;p&gt;After you clicked you will see a configuration page, there we going to configure all the needed parameters for our load balancer.&lt;/p&gt;

&lt;p&gt;The first step is to provide a name, and we going to keep the internet access and the IPv4 options selected, like in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tXTEB5z0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3352/1%2AREQwtfISS1Tfs_X6mevEbA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tXTEB5z0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3352/1%2AREQwtfISS1Tfs_X6mevEbA.png" alt="" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to configure the network mapping.&lt;/p&gt;

&lt;p&gt;Here we going to configure the VPC and the availability zones.&lt;/p&gt;

&lt;p&gt;For the VPC you can select one of the ones that you already have configured, and then select the AZ and the subnet related to it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dDLaJFqo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3488/1%2AUtlbBRfjTJ9qrPCsXYP1Lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dDLaJFqo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3488/1%2AUtlbBRfjTJ9qrPCsXYP1Lw.png" alt="" width="800" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RWp9cQg0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3264/1%2AImXCdc7l4OlT0rh2eMazjw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RWp9cQg0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3264/1%2AImXCdc7l4OlT0rh2eMazjw.png" alt="" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to configure the security group, in this case, we going to see that is one selected by default, but we need to create a new one used only by our ALB (Application Load Balancer). To do that you need to make click on “Create new security group”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xzZSFsZD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3256/1%2AkBbZxBbl7kxyloZUupnoxQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xzZSFsZD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3256/1%2AkBbZxBbl7kxyloZUupnoxQ.png" alt="" width="800" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_YHxj-5g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3552/1%2AzCyuuTlnzEYg9Pdn9YeuvQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_YHxj-5g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3552/1%2AzCyuuTlnzEYg9Pdn9YeuvQ.png" alt="" width="800" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;we need to add Inbound rules, you can take as example the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Oe3OXYb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3480/1%2AiClRXGehZWufG02MamjN5Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Oe3OXYb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3480/1%2AiClRXGehZWufG02MamjN5Q.png" alt="" width="800" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ready your security group configurations are done just click on “Create security group”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A0RdRy2d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3060/1%2A21pU6ESGCfBXttrgk7AsbQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A0RdRy2d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3060/1%2A21pU6ESGCfBXttrgk7AsbQ.png" alt="" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to the load balancer configuration page and choose your new security group as part of its configurations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3wmpGKDp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3386/1%2APVj9Wn2eyiNMEE8SZcFdjw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3wmpGKDp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3386/1%2APVj9Wn2eyiNMEE8SZcFdjw.png" alt="" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v75l1IHp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3328/1%2Avd6EMZxfVq25UrHwVfU3Fg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v75l1IHp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3328/1%2Avd6EMZxfVq25UrHwVfU3Fg.png" alt="" width="800" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then the following step is one of the most important because there we going to configure all the instances that will be used by our load balancer.&lt;/p&gt;

&lt;p&gt;For the “Listener and routing” configuration we going to follow a couple of steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BxeMyifZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3266/1%2Afc8f3OlRhlACMc6IZM3LsA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BxeMyifZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3266/1%2Afc8f3OlRhlACMc6IZM3LsA.png" alt="" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first one is to create a new “target group”, configured for instances, you can take as a reference the images below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MJgALOcp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3340/1%2AkPPyY7pbfMuWMm6eqR-Siw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MJgALOcp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3340/1%2AkPPyY7pbfMuWMm6eqR-Siw.png" alt="" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h0OjsdMX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2538/1%2AISenxRBhaHVRtM6ft0aGaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h0OjsdMX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2538/1%2AISenxRBhaHVRtM6ft0aGaw.png" alt="" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see we only modified those values, then you can click on “next” to proceed to add the instances&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bodcM-ET--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3290/1%2AVArDTxtYrw7SCnfP87vbmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bodcM-ET--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3290/1%2AVArDTxtYrw7SCnfP87vbmg.png" alt="" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;once selected click on include as pending&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--en7UHCL_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3334/1%2AWOyMl25GYGHhJVs6pBkYYQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--en7UHCL_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3334/1%2AWOyMl25GYGHhJVs6pBkYYQ.png" alt="" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;then click on create.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0zpCCYgK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2938/1%2A33dbNsJJH2xutmWiYrkIYw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0zpCCYgK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2938/1%2A33dbNsJJH2xutmWiYrkIYw.png" alt="" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once configured the target group, you should go back to the load balancer configuration page and select the created target group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--91z43aAa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3318/1%2A9zuiN-ZztHLckmLImK-mOA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--91z43aAa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3318/1%2A9zuiN-ZztHLckmLImK-mOA.png" alt="" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down to see the summary, and then click on create.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7aTiXXcr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3764/1%2AaIKvY_5PocTRZZwTYFMYkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7aTiXXcr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3764/1%2AaIKvY_5PocTRZZwTYFMYkw.png" alt="" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fzBguexW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2978/1%2AyAGsn1lS5kR0QnXvfiatGg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fzBguexW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2978/1%2AyAGsn1lS5kR0QnXvfiatGg.png" alt="" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To test our Load balancer we need to use the DNS name that comes on the load balancer details&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oi5hWuHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2966/1%2Az4cE1KLfTIdVnfpcQo-wtg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oi5hWuHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2966/1%2Az4cE1KLfTIdVnfpcQo-wtg.png" alt="" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy and paste in a browser and then EC2 instance should response&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BPIUVFB1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2216/1%2AzLUmqP0QPV0q3GVcq-PjVA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BPIUVFB1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2216/1%2AzLUmqP0QPV0q3GVcq-PjVA.png" alt="" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe the result will the same many times but if you test doing the request with some tool to help you to get the limit of request the load balancer will make its work and distribute the request.&lt;/p&gt;

&lt;p&gt;Pretty easy right ?. Now you know how to configure manually a load balancer and how to configure the instances that it will run, maybe you are wondering, but, what happens if we don’t want to create or delete the instances and make it automatically?, the answer is, use an Auto Scaling Group (ASG), that will help you to create instances as the demand needs and also it will automatically decrease the number of instances.&lt;/p&gt;

&lt;p&gt;In the next section of this tutorial, we going to see how to use and configure an Auto Scaling group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TthXIGJl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2ATYhNdrSe3cBocmMk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TthXIGJl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2ATYhNdrSe3cBocmMk.png" alt="" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ASG stands for “Auto Scaling Group”, and is a service that helps us to scale our application automatically monitoring our EC2 containers and increasing or decreasing the instances as needed based on the traffic and request on your instances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5WiwNMJ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AU3fOHiHTjEIoi7gC2CwTLA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5WiwNMJ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AU3fOHiHTjEIoi7gC2CwTLA.png" alt="" width="800" height="706"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Benefits and features&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fault tolerance&lt;/strong&gt;:&lt;br&gt;
Detect when an instance is unhealthy, terminate it, and launch an instance to replace it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Availability:&lt;br&gt;
**Ensure that your application always has the right amount of capacity to handle the current traffic demand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Cost management:&lt;br&gt;
**Save money by dynamically launching instances when they are needed and terminating them when they aren’t.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One example could be the following. If an application experiences a sudden increase in workload, Amazon Auto Scaling can automatically add more computing resources to ensure that the application continues to function smoothly. Similarly, if the workload decreases, Amazon Auto Scaling can automatically reduce the number of computing resources to avoid unnecessary costs.&lt;/p&gt;

&lt;p&gt;Knowing that is time to build our ASG and see it in action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring ASG
&lt;/h3&gt;

&lt;p&gt;The first step to configure a ASG is to go to the ASG dashboard, you can access making click in the “Auto Scaling Groups” in the left menu. And then select “create auto scaling group”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Kens0EKB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AK7kgf8c6pggYWnQLLVXhMw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Kens0EKB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AK7kgf8c6pggYWnQLLVXhMw.png" alt="" width="470" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Doing that you will see the following page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1rVrmJBr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4812/1%2ADta7OLnBLT0mDIf0ektPrw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1rVrmJBr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4812/1%2ADta7OLnBLT0mDIf0ektPrw.png" alt="" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we going to start with the configurations. As you can see there are 7 steps to follow, and I will guide you on each one of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here we need to provide a name and create the launch template for our instances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jFQDD0Uu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4560/1%2AOuReZOUyN8oJRWy6qGLzbA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jFQDD0Uu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4560/1%2AOuReZOUyN8oJRWy6qGLzbA.png" alt="" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to create the template you should make click on “Create launch template”&lt;/p&gt;

&lt;p&gt;There you can take as a base the following configurations (just focus in the edited sections for this tutorial):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kpblwrcz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3300/1%2AVeM6fr6_RkWgdXtZNN94Hg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kpblwrcz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3300/1%2AVeM6fr6_RkWgdXtZNN94Hg.png" alt="" width="800" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---L7uB3c7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3272/1%2ASjliMwKhDXpsuicQ3mjBdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---L7uB3c7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3272/1%2ASjliMwKhDXpsuicQ3mjBdg.png" alt="" width="800" height="767"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AE7frvbu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2250/1%2AA6OgE8l1vz1WmnKtawfyQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AE7frvbu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2250/1%2AA6OgE8l1vz1WmnKtawfyQw.png" alt="" width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the network settings you need to provide a valid security group. You could use the same that we used in the previous sections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jimvGhLZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2178/1%2AA4j1-9y5o2HxXjOVXLR3vA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jimvGhLZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2178/1%2AA4j1-9y5o2HxXjOVXLR3vA.png" alt="" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--We_CbEnF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2192/1%2AsO_sV-VJeU1VV7H5hYqXqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--We_CbEnF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2192/1%2AsO_sV-VJeU1VV7H5hYqXqw.png" alt="" width="800" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pW-PNAnK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2Ac9bBr4Hu6-Oc-jic6112Yw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pW-PNAnK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2Ac9bBr4Hu6-Oc-jic6112Yw.png" alt="" width="800" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have the configurations make click on create launch template&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KZ_qSzao--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3388/1%2AzxU44tSRTrk6CAPXSdh_vA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KZ_qSzao--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3388/1%2AzxU44tSRTrk6CAPXSdh_vA.png" alt="" width="800" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then go back to the ASG view, there you need to choose the created template&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5tbRYAH2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2382/1%2Axrdh_nI99k_-2FaQkk0QvA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5tbRYAH2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2382/1%2Axrdh_nI99k_-2FaQkk0QvA.png" alt="" width="800" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;click on next.&lt;/p&gt;

&lt;p&gt;select your VPC and at least 2 subnets with internet access. here you can use the configured in the previous section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nq4JL1Hy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2344/1%2Apktgv2WanTznafesRGC6XA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nq4JL1Hy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2344/1%2Apktgv2WanTznafesRGC6XA.png" alt="" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on next.&lt;/p&gt;

&lt;p&gt;In this step you need to specify which load balancer the ASG will use, then you can select the one that we created in the previous sections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NqjomC_s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2434/1%2AimBXL90TvpAPYLpj3n-8mw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NqjomC_s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2434/1%2AimBXL90TvpAPYLpj3n-8mw.png" alt="" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YkfHrFhp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2400/1%2A-udmGjT5bofp6chmhLouKA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YkfHrFhp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2400/1%2A-udmGjT5bofp6chmhLouKA.png" alt="" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Itl2rAwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2416/1%2Ar9oh_zCw8SYeWmRyQ54Dxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Itl2rAwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2416/1%2Ar9oh_zCw8SYeWmRyQ54Dxg.png" alt="" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on next.&lt;/p&gt;

&lt;p&gt;The fourth step is to configure the ASG size, defining the number of instances to use.&lt;/p&gt;

&lt;p&gt;You can use the following configurations:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KCbaLnjg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2426/1%2Ak7KFV-54xoX8tivCkorDtg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KCbaLnjg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2426/1%2Ak7KFV-54xoX8tivCkorDtg.png" alt="" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jtzMVEoO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2454/1%2AtU0FEQLALtBk8_5UmbtuHw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jtzMVEoO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2454/1%2AtU0FEQLALtBk8_5UmbtuHw.png" alt="" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on next until step 7. we going to omit the others configurations in this tutorial.&lt;/p&gt;

&lt;p&gt;Then click on create.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yt36qLhL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3618/1%2AjXUluyoWfQGwsD35RrXfTA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yt36qLhL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3618/1%2AjXUluyoWfQGwsD35RrXfTA.png" alt="" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see we have a new ASG created.&lt;/p&gt;

&lt;p&gt;If you go to the EC2 instances you also will see 2 instances created by default and automatically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ttjcB1_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3076/1%2AEebKh_s8jYYUax4tulTMYQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ttjcB1_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3076/1%2AEebKh_s8jYYUax4tulTMYQ.png" alt="" width="800" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait a bit until the instances are running, in order to test the results. We need to go to our Load Balancer and get the DNS to make the request in a browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FP4ZPKJU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AkTn2ooyDqbZQYqFl0PPeEQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FP4ZPKJU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AkTn2ooyDqbZQYqFl0PPeEQ.png" alt="" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At time to load the page you will see in the screen the IP related to the instance that is getting your request.&lt;/p&gt;

&lt;p&gt;Ready as you can see we now you know how to start configuring a load balancer for your system, and make an auto scaling group to make the scaling automatically.&lt;/p&gt;

&lt;p&gt;I recommend to you to use the ASG because it will help you to manage the instances adding or removing them as needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cR7R5KHP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AdEKIv46P7fq8pG45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cR7R5KHP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AdEKIv46P7fq8pG45.png" alt="" width="400" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Golang context</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Wed, 28 Jun 2023 04:40:04 +0000</pubDate>
      <link>https://dev.to/josueparra2892/golang-context-4n8g</link>
      <guid>https://dev.to/josueparra2892/golang-context-4n8g</guid>
      <description>&lt;h2&gt;
  
  
  Golang context
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F0%2AUQfVYBx-OJCLUZuN.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F0%2AUQfVYBx-OJCLUZuN.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The official documentation mention provides the following description:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In other words, the context helps us to define scopes in our different processes and control when each one needs to be completed or terminated according to the parent process results.&lt;/p&gt;

&lt;p&gt;One common example of the use of context is when we are working with APIs, then we define (or the used framework) the parent context that should be shared along the request process. In that kind of context, we have all the information related to the request one good example is the &lt;a href="https://github.com/gin-gonic/gin" rel="noopener noreferrer"&gt;*gin-gonic&lt;/a&gt;* framework, where its developers make very good use of the context along with the requests.&lt;/p&gt;

&lt;p&gt;Another example is the use of goroutines, in that case, we could implement the context and some of its main functions to ensure to termination of the subprocess and reduce resource costs.&lt;/p&gt;

&lt;p&gt;Contexts are particularly useful in situations where you need to perform multiple operations concurrently and you want centralized control over their execution. For example, contexts can be used to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set deadlines for trades and cancel them if they take too long.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Propagate shared values, such as authentication or configuration information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide abort signals to goroutines and functions that use the context.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide diagnostic information such as traces and logs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Golang is an important tool for concurrent programming and helps us provide additional information through function calls and goroutines safely and efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context TODO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Code should use context.TODO when it’s unclear which Context to use or it is not yet available (because the surrounding function has not yet been extended to accept a Context parameter)”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context Background&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“context.Background returns a non-nil, empty Context. It is never canceled, has no values, and has no deadline. It is typically used by the main function, initialization, and tests, and as the top-level Context for incoming requests”&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context Functions
&lt;/h3&gt;

&lt;p&gt;In this section, I will show you some of the most used context functions context.WithCancel and context.WitTimeout , both are similar, helping us to close the subprocess from the parent context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WithCancel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;context.WithCancel() is a function in Golang that is used to create a new context from a parent context and a cancel function that is used to cancel the child context and all its related goroutines.&lt;/p&gt;

&lt;p&gt;The context.WithCancel() function takes a parent context as an argument and returns two values: a child context and a cancel function. The child context is a new context that is derived from the parent context and includes additional information such as a cancellation signal. The cancel function is used to cancel the child context and all related goroutines.&lt;/p&gt;

&lt;p&gt;Here is one example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
 "context"
 "fmt"
)

func main() {
 // gen generates integers in a separate goroutine and
 // sends them to the returned channel.
 // The callers of gen need to cancel the context once
 // they are done consuming generated integers not to leak
 // the internal goroutine started by gen.
 gen := func(ctx context.Context) &amp;lt;-chan int {
    dst := make(chan int)
    n := 1
    go func() {
       for {
          select {
            case &amp;lt;-ctx.Done():
               return // returning not to leak the goroutine
            case dst &amp;lt;- n:
               n++
          }
       }
    }()
    return dst
 }

 ctx, cancel := context.WithCancel(context.Background())
 defer cancel() // cancel when we are finished consuming integers

 for n := range gen(ctx) {
    fmt.Println(n)
    if n == 5 {
       break
    }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;WithTimeout&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;context.WithTimeout() is a function in Golang that is used to create a new context from a parent context with a timeout duration. The timeout duration specifies how long the context and all its related goroutines should wait before canceling automatically.&lt;/p&gt;

&lt;p&gt;The context.WithTimeout() function takes a parent context and a timeout duration as arguments and returns two values: a child context and a cancel function. The child context is a new context that is derived from the parent context and includes additional information such as a deadline for canceling the context. The cancel function is used to cancel the child context and all related goroutines.&lt;/p&gt;

&lt;p&gt;Here is one example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
 "context"
 "fmt"
 "time"
)

const shortDuration = 1 * time.Millisecond

func main() {
   // Pass a context with a timeout to tell a blocking function that it
   // should abandon its work after the timeout elapses.
   ctx, cancel := context.WithTimeout(context.Background(), shortDuration)
   defer cancel()

   select {
     case &amp;lt;-time.After(1 * time.Second):
        fmt.Println("overslept")
     case &amp;lt;-ctx.Done():
        fmt.Println(ctx.Err()) // prints "context deadline exceeded"
   }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context deadline exceeded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Another example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    // Create a parent context using `context.Background()`
    ctx := context.Background()

    // Create a child context with a timeout of 2 seconds using `context.WithTimeout()`
    ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
    defer cancel()

    // Simulate a long-running task that takes 3 seconds to complete
    go longRunningTask(ctx)

    // Wait for the child context to be canceled or to timeout
    select {
    case &amp;lt;-ctx.Done():
        fmt.Println(ctx.Err())
    case &amp;lt;-time.After(3 * time.Second):
        fmt.Println("Task took too long to complete")
    }

    fmt.Println("Done.")
}

func longRunningTask(ctx context.Context) {
    fmt.Println("Task started.")

    // Simulate a task that takes 3 seconds to complete
    select {
    case &amp;lt;-time.After(3 * time.Second):
        fmt.Println("Task completed.")
    case &amp;lt;-ctx.Done():
        fmt.Println(ctx.Err())
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task started.
context deadline exceeded
Done.

Program exited.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, the Golang context package provides a powerful mechanism for managing and communicating between goroutines. Allowing you to manage deadlines, cancellations and request scope values across API boundaries and between processes.&lt;/p&gt;

&lt;p&gt;By using the context package, you can write concurrent code that is efficient, safe, and easy to reason with.&lt;/p&gt;

&lt;p&gt;Provides a standardized way to propagate request-scoped values, such as authentication tokens or tracking information, across multiple API functions and boundaries.&lt;/p&gt;

&lt;p&gt;It allows you to manage the lifetime of goroutines in a clean and consistent way, making it easy to prevent resource leaks and manage system resources efficiently.&lt;/p&gt;

&lt;p&gt;Overall, the context pack is an essential part of writing scalable, robust, and efficient concurrent applications in Golang.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Information is taken from the official web seite &lt;a href="https://pkg.go.dev/context" rel="noopener noreferrer"&gt;https://pkg.go.dev/context&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4000%2F0%2ALOCwZPeKjzxlvLOt" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4000%2F0%2ALOCwZPeKjzxlvLOt"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Elastic search</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Sat, 24 Jun 2023 20:50:12 +0000</pubDate>
      <link>https://dev.to/josueparra2892/elastic-search-1n71</link>
      <guid>https://dev.to/josueparra2892/elastic-search-1n71</guid>
      <description>&lt;h2&gt;
  
  
  Elastic search
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hands-on Important concepts
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5AfBIz_y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4000/0%2AaDa3IPdDBSf8g3W7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5AfBIz_y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4000/0%2AaDa3IPdDBSf8g3W7.png" alt="" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, I will show you some of the main concepts that we should know when we start to work with Elastic Search.&lt;/p&gt;

&lt;p&gt;I’ll group them as questions &amp;amp; answers to make them more readable and easy to understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is elastic search?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Elasticsearch is a distributed search engine based on Lucene that is used to index and search large amounts of data in real-time. It is designed to be highly scalable and allows for parallel data processing across multiple nodes in a cluster.&lt;/p&gt;

&lt;p&gt;Elasticsearch also offers a wide range of additional functionalities, such as data aggregation, result segmentation, geospatial search, multi-language search, and cluster management. Additionally, it integrates with a variety of data analysis and visualization tools, making it very versatile and easy to use.&lt;/p&gt;

&lt;p&gt;Is a powerful and scalable platform for indexing and searching large amounts of data in real time. It uses a distributed architecture and offers a wide variety of functionalities to facilitate indexing, searching, and visualizing the data&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is an index?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--25czThYt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ALBqbrkpLsQr5hrUEmQ1KNw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--25czThYt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ALBqbrkpLsQr5hrUEmQ1KNw.png" alt="" width="220" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Elasticsearch, an index is a structure that stores data in a format optimized for search and analysis. Indexes contain documents, which are the basic information objects in Elasticsearch. Each document has a unique identifier and contains one or more fields that contain data.&lt;/p&gt;

&lt;p&gt;The indexing process in Elasticsearch begins when a document is sent to the search engine via a REST API &lt;em&gt;(you can see the answer related to index EP to more information)&lt;/em&gt;. When elastic search gets the request, the document is stored in one or more shards and indexed so that it can be searched.&lt;/p&gt;

&lt;p&gt;Indexing involves analyzing the document to extract tokens (keywords) and storing them in a structure optimized for searching. The tokens are mapped to terms, which are indexed in an inverted term tree, which points to the documents that contain each term.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indexing example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s say we want to index a collection of documents containing information about products in an online store. Each document contains information such as the product name, description, price, and category.&lt;/p&gt;

&lt;p&gt;The first step is to create an index in Elasticsearch to store the product-related documents. The index is divided into multiple shards for greater efficiency and scalability.&lt;/p&gt;

&lt;p&gt;Then, we send each document to Elasticsearch using the REST API. Elasticsearch going to analyze the document in order to extract tokens and stores them in its search structure.&lt;/p&gt;

&lt;p&gt;Taking the online store example, we send a document that contains information about blue jeans, and is indexed by the following tokens: “jean”, “blue”, “man”, “casual”, “clothing”, etc. That will help us to make searches using by example: “man jean”, “blue clothing”, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How to use indexes on elastic search?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Indexes are used to store and search data in Elasticsearch. Each index has settings that include text parsing, storage settings, and search settings. Specific settings can also be assigned to each field in an index, allowing for a more precise and personalized search.&lt;/p&gt;

&lt;p&gt;Here is a simple example of how to create an index in Elasticsearch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Log in to Elasticsearch and create an index called “my_index”:&lt;/p&gt;

&lt;p&gt;PUT /mi_indice&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a document to the “my_index” index with a unique identifier and some fields:&lt;/p&gt;

&lt;p&gt;PUT /mi_indice/_doc/1&lt;br&gt;
{&lt;br&gt;
  "name": "Juan Perez",&lt;br&gt;
  "age": 30,&lt;br&gt;
  "address": "Calle 123, Ciudad de México"&lt;br&gt;
}&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Find the document we just added using the Elasticsearch API:&lt;/p&gt;

&lt;p&gt;GET /mi_indice/_search&lt;br&gt;
{&lt;br&gt;
  "query": {&lt;br&gt;
    "match": {&lt;br&gt;
      "name": "Juan"&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This example searches for the document that contains the name “John” in the “name” field of the “my_index” index.&lt;/p&gt;

&lt;p&gt;In short, indices in Elasticsearch are structures that are used to store and search data. They can be customized to suit your specific application requirements and can hold millions of documents with fast and efficient search.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CZcCskbk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AsFFO7iEL_ruENI_D0PQ4PQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CZcCskbk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AsFFO7iEL_ruENI_D0PQ4PQ.png" alt="" width="721" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What are the endpoints related to indexes?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;These are some of the more common index-related endpoints in Elasticsearch, but there are many others available. Each of these endpoints can be customized with additional parameters based on your specific application requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create an index:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;**&lt;em&gt;Endpoint signature: **PUT /.&lt;br&gt;
The request body contains the data of the document that is going to be created or updated in the specified index. The format of the request body should be JSON and it should comply with the mapping structure defined for the index.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example of request body:&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "title": "Example Document",
  "description": "This is an example document for Elasticsearch",
  "tags": ["example", "elasticsearch"],
  "date": "2022-03-28T10:00:00Z"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Delete an index:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Endpoint signature: **DELETE /.&lt;br&gt;
**This endpoint doesn’t not requires of request body, you only need to provide the index to delete. This endpoint will delete the index and all the documents associated to it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get information about an index&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Endpoint signature: **GET /.&lt;br&gt;
**This endpoint doesn’t requires request object and will response with the information related to the provided index.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get statistics about an index&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Endpoint signature: **GET //_stats.&lt;br&gt;
**The endpoint returns a JSON object that contains detailed statistics about the provided index, including the total number of documents, the size of the index in bytes, the number of shards and replicas, and other important details such as the number of indexing, deletion, and search operations that have been performed on the index.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example response:&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "_all": {
    "primaries": {
      "docs": {
        "count": 10000,
        "deleted": 0
      },
      "store": {
        "size_in_bytes": 2000000
      },
      "indexing": {
        "index_total": 20000,
        "index_time_in_millis": 10000
      }
    },
    "total": {
      "docs": {
        "count": 20000,
        "deleted": 0
      },
      "store": {
        "size_in_bytes": 4000000
      },
      "indexing": {
        "index_total": 40000,
        "index_time_in_millis": 20000
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Find documents in an index&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Endpoint signature **GET //_search.&lt;br&gt;
**This endpoint doesn’t require a request object. It is used to search for documents in a specific index using a search query, and the query parameters are specified in the URL.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The possible query params for this endpoint are the following:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**&lt;em&gt;q: **specifies the search query as a simple query string. For example, q=elasticsearch will search for documents containing the word “elasticsearch” in any field.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;**size&lt;/em&gt;&lt;em&gt;: specifies the maximum number of documents to return in the response.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;**from&lt;/em&gt;&lt;em&gt;: specifies the index of the first document to return in the response (useful for pagination).&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;**sort&lt;/em&gt;&lt;em&gt;: specifies the field or fields to sort the search results by.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;**_source&lt;/em&gt;&lt;em&gt;: specifies the fields to include or exclude from the response.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;**aggregations&lt;/em&gt;&lt;em&gt;: allows aggregations to be performed on the search results.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Response example:&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "took": 15,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "field1": "elasticsearch",
          "field2": "kibana",
          "field3": "logstash"
        }
      },
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.5,
        "_source": {
          "field1": "elasticsearch",
          "field2": "logstash",
          "field3": "kibana"
        }
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Update a document in an index&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Endpoint signature: **POST //_update/&lt;/em&gt;&lt;em&gt;.&lt;br&gt;
This endpoint is used to update a specific document in an index by providing a partial document that contains only the fields to be updated.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Parameters:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;**index&lt;/em&gt;&lt;em&gt;: The name of the index that contains the document to be updated.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;**identifier&lt;/em&gt;&lt;em&gt;: The unique identifier of the document to be updated.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;**wait_for_active_shards&lt;/em&gt;&lt;em&gt;: (Optional) The number of active shards that must be available before the update operation returns.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;**routing&lt;/em&gt;&lt;em&gt;: (Optional) The routing value that is used to route the update request to a specific shard.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This endpoint needs a request object with the document information to update, for example: To change the name property.&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "doc": {
    "name": "New Name"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;How many documents could be related to elastic search indexes?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The number of documents that can belong to the same index in Elasticsearch depends on several factors, such as the size of the documents, available hardware, amount of memory, and Elasticsearch configuration.&lt;/p&gt;

&lt;p&gt;In theory, Elasticsearch can handle billions of documents in a single index. However, it’s a good idea to split your indexes into manageable sizes for ease of administration and improved performance.&lt;/p&gt;

&lt;p&gt;Also, it’s important to note that the larger the number of documents in an index, the more resources Elasticsearch will need to index and search those documents. If the index is too large for the available hardware, there may be performance and responsiveness issues.&lt;/p&gt;

&lt;p&gt;In general, it’s a good idea to break your indexes down to manageable sizes and tune your Elasticsearch configuration to optimize performance and scalability based on your application requirements.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;What is a reindexing process and how it works?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you perform a reindex in Elasticsearch, you are copying data from an existing index to a new index. The reindexing process is done for various reasons, such as optimizing performance, changing the index structure, and making configuration adjustments, among others.&lt;/p&gt;

&lt;p&gt;When doing a reindex, the documents from the old index are copied to the new index. In some cases, this can take time and consume considerable resources, especially for large data sets. However, once the reindexing process is complete, you will have a new index that reflects the necessary changes.&lt;/p&gt;

&lt;p&gt;Some of the common reasons for reindexing in Elasticsearch are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Change index structure: Can be reindexed to change field mapping or add new fields to an existing index.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Performance optimization: Reindexing can improve search and indexing performance by removing unnecessary documents or removing outdated indexes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elasticsearch version upgrade: A reindex may be required when upgrading Elasticsearch to a later version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Index consolidation — Multiple indexes can be combined into a single index, which can make administration easier and improve query performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By performing a reindex in Elasticsearch, you can update and optimize the data in an index to improve performance and tailor it to specific application requirements. However, it is important to carefully plan and test the reindexing process in a test environment before running it in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is the reindexing process?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reindexing in Elasticsearch is a process that involves creating a new index and copying data from an existing index into the new index with possible modifications to the index structure. This is done to reorganize the data, change the index structure, and optimize performance, among other reasons.&lt;/p&gt;

&lt;p&gt;The reindexing process is done in several steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Creation of a new index: A new index is created with the desired structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data source configuration: The data source is configured, which can be an existing index or a query that returns documents.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configuration of the reindexing process: The reindexing process is configured, which includes the data source and the new index.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execution of the reindexing process: The reindexing process starts. Elasticsearch reads the documents from the data source and writes them to the new index.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verification of the reindexing process: It is verified that all documents have been reindexed correctly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is important to note that the reindexing process can be costly process in terms of resources and time, especially on large data sets. Therefore, it is recommended to carefully plan and test the process in a test environment before reindexing in production.&lt;/p&gt;

&lt;p&gt;There is an endpoint that helps us to make that process, and I going to define and show you how it is used:&lt;/p&gt;

&lt;p&gt;Endpoint signature: &lt;strong&gt;POST /_reindex&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;**&lt;em&gt;Request body:&lt;br&gt;
**To reindex an index, you’ll need to provide a request body that specifies the source and destination indices, as well as any other options you want to use. The request body can be quite complex, but here’s a simple example that reindexes all documents from an index called “my_index” to a new index called “my_index_v2”:&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "source": {
    "index": "my_index"
  },
  "dest": {
    "index": "my_index_v2"
  }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Additional params:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;wait_for_completion&lt;/strong&gt;: If set to false, the request will return immediately and the reindexing process will continue in the background. Otherwise, the request will block until the reindexing is complete.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;refresh&lt;/strong&gt;: If set to true, the destination index will be refreshed after each batch of documents is indexed. This can be useful if you want to perform searches on the new index while it’s being reindexed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;requests_per_second&lt;/strong&gt;: The maximum number of requests per second to send to Elasticsearch while reindexing. This can be used to limit the impact of the reindexing process on your Elasticsearch cluster.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example response:&lt;/strong&gt;&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{&lt;br&gt;
  "task": {&lt;br&gt;
    "node": "ABC123",&lt;br&gt;
    "id": 12345,&lt;br&gt;
    "type": "transport",&lt;br&gt;
    "action": "indices:data/write/reindex",&lt;br&gt;
    "start_time_in_millis": 1621234567890,&lt;br&gt;
    "running_time_in_nanos": 1234567890,&lt;br&gt;
    "cancellable": true&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  &lt;strong&gt;When reindexing in elastic search, does the search results change with the _search endpoint?&lt;/strong&gt;&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;The short answer is yes.&lt;/p&gt;

&lt;p&gt;when performing a reindex in Elasticsearch, it is possible that the search results will change when using the _search endpoint.&lt;/p&gt;

&lt;p&gt;This is because the reindexing process involves creating a new index and copying the documents from the original index to the new index with possible modifications in the process. Therefore, if changes have been made to the data structure, such as removing or adding new fields, or modifications have been made to existing data, the search results may change after reindexing.&lt;/p&gt;

&lt;p&gt;Also, it is important to note that the reindexing process can take time depending on the size of the index and the configuration of Elasticsearch. During the reindexing process, some documents may not be available for search until all steps in the process are completed.&lt;/p&gt;

&lt;p&gt;Therefore, it is recommended to perform extensive testing after reindexing to ensure that the search results are consistent and match the expectations of the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Could be there some issues after the reindexing process?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;After reindexing in Elasticsearch, search errors may occur in the new index. Here are some suggestions found that could be helpful for troubleshooting search issues after reindexing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Verify that documents have been indexed correctly: Some documents may not have been indexed correctly during the re-indexing process. Verify that documents have been indexed correctly and are available for search.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify that fields have been indexed correctly: If you added new fields during the reindexing process, make sure that they have been indexed correctly and are available for search.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify search query syntax: If you changed the data structure during the reindexing process, you may need to adjust the syntax of search queries to match the new data structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify analysis settings: If you added new text fields during the reindexing process, you may need to adjust the analysis settings to match the new text fields. Analysis settings affect how Elasticsearch indexes and searches text in the index.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run search queries on multiple nodes: If you are using an Elasticsearch cluster, there may be data inconsistencies between nodes during the re-indexing process. Run search queries on multiple nodes to verify that results are consistent across the cluster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check Elasticsearch logs: If you still have search issues after verifying the above steps, check Elasticsearch logs for detailed information about any index or search issues. Elasticsearch logs can provide valuable information for troubleshooting search issues after reindexing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What are aliases?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The alias, on the other hand, is a way to refer to one or more indices with a single name. It is useful in situations where you need to access multiple indices simultaneously, as it allows you to refer to them in a simpler and more organized way. Aliases can also be used to rename an existing index, reindex an index, and change the number of shards and/or replicas, without affecting the applications that use the index.&lt;/p&gt;

&lt;p&gt;The use of indices and aliases in Elasticsearch is essential for organizing and accessing data efficiently. Indices are the basic unit of storage, while aliases allow you to refer to one or more indices with a single name and perform actions on them jointly.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What are the endpoints related to aliases?&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create alias for existing index: PUT /&amp;lt;index&amp;gt;/_aliases/&amp;lt;alias&amp;gt;&lt;br&gt;
Get information about an alias: GET /_aliases/&amp;lt;alias&amp;gt; &lt;br&gt;
List Aliases: GET /_alias&lt;br&gt;
Create or remove multiple aliases at the same time: POST /_aliases&lt;br&gt;
Delete alias: DELETE /&amp;lt;index&amp;gt;/_alias/&amp;lt;alias&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Final notes:&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;As I mentioned many times, this article doesn’t show you all the needed to work with the elastic search but could be helpful to help you to solve some of the basic doubts that you have when learning this interesting technology.&lt;/p&gt;

&lt;p&gt;If you want to learn more I recommend going to the official documentation or visiting this very good site &lt;a href="https://opster.com/elasticsearch-guides/"&gt;Opster&lt;/a&gt; there you will find real-world examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks for reading!
&lt;/h2&gt;

</description>
    </item>
    <item>
      <title>Books that help us to be better developers</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Sat, 24 Jun 2023 20:41:53 +0000</pubDate>
      <link>https://dev.to/josueparra2892/books-that-help-us-to-be-better-developers-2365</link>
      <guid>https://dev.to/josueparra2892/books-that-help-us-to-be-better-developers-2365</guid>
      <description>&lt;h2&gt;
  
  
  Books that help us to be better developers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Time to be a software craftsman
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bl3_ejNd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ACYh0laI2co1bzB3KBixNZw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bl3_ejNd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ACYh0laI2co1bzB3KBixNZw.png" alt="" width="469" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, I want to share with you a list of the most representative books that have helped me to be a better developer, I’m sure that I’m not the only case and a lot of developers share the same feelings about those books.&lt;/p&gt;

&lt;p&gt;Part of the professional growth of a software developer is reading and learning more technical terms that help us to write and design better codes, In my personal case I found help from the list of books that I’ll mention and I’m very glad to share with you and try to help you to find a very good way to get knowledge.&lt;/p&gt;

&lt;p&gt;Sometimes we as developers find information in forums or posts but some of times we understand how to implement and how to use the technology or technics that we are searching, but some of the times we need to go deeper and investigate more about the reasons about why is recommended to do that. That take me year ago to investigate and find that books that some times were recommended by friends or for software architects that help me to be better developer.&lt;/p&gt;

&lt;p&gt;Just as I learned, now is the time to help others to find a way to be better and perform the knowledge that we have.&lt;/p&gt;

&lt;p&gt;The following list of books is recommended for any developer level you can be a jr, a mid, or a senior, doesn’t matter the level, the important is to become into a software craftsman.&lt;/p&gt;

&lt;p&gt;Lets statrt with the list:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Ixc0HVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3712/1%2A4t-QJi21fjqrVVDW9Q30ZA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Ixc0HVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3712/1%2A4t-QJi21fjqrVVDW9Q30ZA.png" alt="" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Robert C. Martin (Uncle Bob)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bSbRycjS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AhqxLtcep_7b7j8kJ.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bSbRycjS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AhqxLtcep_7b7j8kJ.jpg" alt="" width="473" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This guy is a renowned author and programming expert. The books that I could recommend are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clean Code: A Handbook of Agile Software Craftsmanship&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Clean Coder: A Code of Conduct for Professional Programmers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clean Architecture: A Craftsman’s Guide to Software Structure and Design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Software Craftsman, the professionalism, Pragmatism, Pride&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zyFPajxP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AN7rMMvPXOcRaRrLc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zyFPajxP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AN7rMMvPXOcRaRrLc.jpg" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you recommend another book from this author please add it on the comments and then everybody could learn more :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Eric Evans
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VFYN2iOD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2A1scJ1ymqweVRqf2d.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VFYN2iOD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2A1scJ1ymqweVRqf2d.jpg" alt="" width="400" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an author and expert in object-oriented software development and modeling complex domains. He is best known for his book “Domain-Driven Design: Tackling Complexity in the Heart of Software,” which is considered a classic in the software development field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c-O48B6q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2A2-5bAuBEhBtKDEMl7PLs7Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c-O48B6q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2A2-5bAuBEhBtKDEMl7PLs7Q.png" alt="" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Domain-Driven Design Reference: Definitions and Pattern Summaries&lt;/strong&gt;: a reference book that provides definitions of key terms and summaries of patterns used in domain-driven design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Implementing Domain-Driven Design&lt;/strong&gt;: a book that explores how to apply the principles and patterns of domain-driven design in the real world.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you recommend another book from this author please add it on the comments and then everybody could learn more :)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Vaughn Vernon&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AJa2PFjt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2ACvHQPaHEFQMjOqAq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AJa2PFjt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2ACvHQPaHEFQMjOqAq.jpg" alt="" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is an author and expert in object-oriented software development and domain-driven design.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Implementing Domain-Driven Design&lt;/strong&gt;: a book that provides a practical guide to implementing domain-driven design principles in software development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GNPCUyHE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2880/1%2AMrbu59orukJ7WJNWQZGFhA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GNPCUyHE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2880/1%2AMrbu59orukJ7WJNWQZGFhA.png" alt="" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you recommend another book from this author please add it on the comments and then everybody could learn more :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Murat Erder
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Architecture in Practice&lt;/strong&gt;: Software Architecture in the Age of Agility and Devops: he book discusses how software architecture can be integrated into an agile and DevOps environment to help organizations achieve greater agility, quality, and innovation in their software development practices. It covers topics such as the principles of continuous architecture, the role of architects in agile and DevOps teams, architectural governance, and architectural practices such as modularization, microservices, and cloud computing. The book also provides practical guidance on how to implement continuous architecture in real-world scenarios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iBR2hlr4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3584/1%2A_05UZNZdOC11E7HsfU9B7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iBR2hlr4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3584/1%2A_05UZNZdOC11E7HsfU9B7g.png" alt="" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Martin fowler
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ID1ttv9G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3866/0%2AU8QT4Y89wcOSrs7T.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ID1ttv9G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3866/0%2AU8QT4Y89wcOSrs7T.jpg" alt="" width="800" height="610"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is a well-known software developer, author, and speaker. Some of his most well-known books include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Refactoring: Improving the Design of Existing Code&lt;/strong&gt;: a book that provides guidance on how to improve the design of existing code through refactoring techniques.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Patterns of Enterprise Application Architecture&lt;/strong&gt;: a book that presents patterns for designing enterprise applications, such as Data Mapper, Service Layer, and Table Module.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Domain-Specific Languages&lt;/strong&gt;: a book that explains how to design and implement domain-specific languages (DSLs) for specific problem domains.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JyR7KQ6x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3428/1%2Aa0KjJguMigv1oaAIervNQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JyR7KQ6x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3428/1%2Aa0KjJguMigv1oaAIervNQw.png" alt="" width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you recommend another book from this author please add it on the comments and then everybody could learn more :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Andrew Hunt, David Thomas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;**The Pragmatic Programmer: Your Journey to Mastery: **It is a classic in the software development industry and provides practical advice on how to become a better programmer and improve your skills over time. The book covers a wide range of topics, including software design, coding techniques, debugging, testing, and project management. It also emphasizes the importance of teamwork, communication, and continuous learning in software development. The book is written in a conversational tone and includes real-world examples to illustrate its principles. It has been widely praised for its practicality and readability and is recommended for software developers at all levels of experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jpDfzcN4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3572/1%2Ai_a9f9LiKKXe1FMfRoG6qQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jpDfzcN4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3572/1%2Ai_a9f9LiKKXe1FMfRoG6qQ.png" alt="" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Richard N. Taylor, Nenad Medvidovic, and Eric M. Dashofy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Software Architecture: Foundations, Theory, and Practice&lt;/strong&gt;: The book provides a comprehensive introduction to software architecture, covering topics such as architectural styles, patterns, and tactics, as well as the principles and practices of software architecture. It also discusses the role of software architects and the importance of communication and collaboration in architecture design. The book includes case studies and examples from real-world software projects to illustrate its principles and provide practical guidance. It has been widely praised for its depth and breadth of coverage and is recommended for software architects, developers, and project managers who are interested in software architecture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vKtUAiiu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2136/1%2A80tTeY5sEKQLSNTKVwyWvQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vKtUAiiu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2136/1%2A80tTeY5sEKQLSNTKVwyWvQ.png" alt="" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final notes
&lt;/h2&gt;

&lt;p&gt;Those are some of the books that I could recommend to you in order to improve your skills.&lt;/p&gt;

&lt;p&gt;Feel free to recommend any other book helpful for software developers.&lt;/p&gt;

&lt;p&gt;And as you can see all the recommended books are not related to some specific programming language, then the knowledge could be applied to most programming languages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xV72FxKx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2A1zoIuUOPwQaS2rjq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xV72FxKx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2A1zoIuUOPwQaS2rjq.jpg" alt="" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
      <category>development</category>
    </item>
    <item>
      <title>Dependency Injection and Dependency Inversion</title>
      <dc:creator>Israel Parra</dc:creator>
      <pubDate>Sat, 24 Jun 2023 20:38:27 +0000</pubDate>
      <link>https://dev.to/josueparra2892/-dependency-injection-and-dependency-inversion-2c45</link>
      <guid>https://dev.to/josueparra2892/-dependency-injection-and-dependency-inversion-2c45</guid>
      <description>&lt;h2&gt;
  
  
  Dependency Injection and Dependency Inversion
&lt;/h2&gt;

&lt;p&gt;Creating and maintaining robust and high-quality software are constant challenges for developers. As systems become more complex, issues such as lack of modularity and difficulty in conducting unit testing arise. To address these problems, design patterns and programming principles promoting the separation of concerns and code reuse have emerged. Two fundamental concepts in this regard are Dependency Injection and Dependency Inversion.&lt;/p&gt;

&lt;p&gt;In this article, we will review the differences and the relations between Dependency Injection and Dependency inversion. Here I will try to help you understand each one because sometimes we could get confused using those terms.&lt;/p&gt;

&lt;p&gt;Let us start with the definitions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency Injection
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--osMOTgMy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2A2PPCDYW31Al-Ltzs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--osMOTgMy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2A2PPCDYW31Al-Ltzs.gif" alt="" width="408" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dependency Injection is a design pattern that allows for the separation of an object’s dependencies from its implementation. Instead of the object creating or searching for its dependencies directly, they are supplied from the outside, providing greater flexibility and ease in conducting unit testing. In this approach, the dependent object is unaware of the details of how its dependencies are created or obtained; it only concerns itself with its usage.&lt;/p&gt;

&lt;p&gt;In terms of Unit testing the dependency injection helps to make it easier. Because by injecting dependencies, alternative or mock implementations of the dependencies can be provided to independently isolate and test the dependent object. This allows for more efficient testing and reduces dependency on external environments or resources that are difficult to replicate in the test environment.&lt;/p&gt;

&lt;p&gt;We can implement Dependency Injection in various ways, such as through a constructor, a configuration method, or by utilizing dependency injection containers. By employing this approach, code modularity is enhanced as dependencies can be easily changed or replaced without impacting the implementation of the dependent object. Furthermore, Dependency Injection facilitates the principle of “programming to an interface, not an implementation,” promoting code reuse and extensibility.&lt;/p&gt;

&lt;p&gt;Let us see a pseudocode example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Definition of a class that depends on an interface

interface ILogger {
  method log(message: string)
}

class UserService {
  private logger: ILogger

  constructor(logger: ILogger) {
    this.logger = logger
  }

  method createUser(username: string) {
    // Logic for creating a user

    // Logging a log message using the ILogger dependency
    this.logger.log("A new user has been created: " + username)
  }
}

// Usage of the UserService class with an ILogger implementation

class ConsoleLogger implements ILogger {
  method log(message: string) {
    // Logic for displaying the log message in the console
    console.log(message)
  }
}

// Creating an instance of UserService and supplying the ILogger implementation

loggerInstance = new ConsoleLogger()
userServiceInstance = new UserService(loggerInstance)

// Using the UserService
userServiceInstance.createUser("john_doe")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;In this example, the UserService class depends on an ILogger interface for logging messages. The concrete implementation ConsoleLogger implements the ILogger interface and provides the functionality of logging messages to the console.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In the constructor of UserService, an instance of ILogger is injected, allowing UserService to use any implementation of ILogger without being tightly coupled to a specific concrete implementation. When the createUser method is called, a message is logged using the supplied ILogger dependency.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By using dependency injection, the ILogger implementation can be easily changed to another one without modifying the logic of UserService. This provides flexibility and facilitates testing and maintaining the code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In short, dependency injection is a technique that promotes the separation of concerns, modularity, and flexibility by supplying the dependencies required by an object from the outside. It provides benefits such as code reuse and ease of unit testing, which contributes to more robust and maintainable software development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency Inversion
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QOB6bpNh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AeV6C7jUSWnOQ5J07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QOB6bpNh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AeV6C7jUSWnOQ5J07.png" alt="" width="716" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dependency inversion is a design principle in programming that states that high-level modules should not depend on low-level modules directly. Instead, both should depend on abstractions or interfaces.&lt;/p&gt;

&lt;p&gt;This principle is applied when we are implementing a layer architecture, then we can say that the lower layers can not make reference to the upper layer. Translating to packages we cold say that inner packages can not make reference to outer packages.&lt;/p&gt;

&lt;p&gt;Rather than a high-level module knowing and depending on the specific implementation details of low-level modules, abstractions or interfaces are introduced between them. This means that high-level modules depend on these abstractions rather than directly depending on low-level modules.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4L3g8tcy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AHMT2pYIkGOjsvO9Y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4L3g8tcy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AHMT2pYIkGOjsvO9Y.png" alt="Example" width="510" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This principle promotes modularity, loose coupling, and flexibility in software design. By using abstractions and interfaces, it becomes possible to change the implementations of low-level modules without affecting the high-level modules. This allows for easy swapping of different implementations without modifying the code of the high-level modules.&lt;/p&gt;

&lt;p&gt;Furthermore, dependency inversion facilitates code reuse. By depending on abstractions instead of concrete implementations, different interchangeable implementations can be used in different contexts or scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;Dependency Inversion and Dependency Injection are closely related and are often used together to achieve a more flexible and modular software design. Dependency Injection allows you to implement dependency inversion by providing abstractions or interfaces through the injection of the corresponding dependencies through the use of interfaces or abstractions.&lt;/p&gt;

&lt;p&gt;In other words, instead of a dependent object being directly attached to a concrete implementation, an implementation is supplied to it via injection using an interface, allowing the dependent object to communicate with its dependency through an abstraction or a interface, thus following the principle of dependency inversion.&lt;/p&gt;

&lt;p&gt;In short, dependency injection is a technique used to implement dependency inversion. It allows the separation of concrete dependencies from dependent objects through the injection of abstractions or interfaces, which facilitates flexibility, decoupling, and code reuse.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
