<?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: Mouloud hasrane</title>
    <description>The latest articles on DEV Community by Mouloud hasrane (@mouloud_hasrane_c99b0f49a).</description>
    <link>https://dev.to/mouloud_hasrane_c99b0f49a</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%2F2362259%2Fac139a2a-c2b6-4bc2-b27e-7da05830f006.jpg</url>
      <title>DEV Community: Mouloud hasrane</title>
      <link>https://dev.to/mouloud_hasrane_c99b0f49a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mouloud_hasrane_c99b0f49a"/>
    <language>en</language>
    <item>
      <title>A deep dive on how backend servers handles HTTP connections</title>
      <dc:creator>Mouloud hasrane</dc:creator>
      <pubDate>Tue, 23 Sep 2025 11:27:31 +0000</pubDate>
      <link>https://dev.to/mouloud_hasrane_c99b0f49a/a-deep-dive-on-how-backend-servers-handles-http-connections-1jom</link>
      <guid>https://dev.to/mouloud_hasrane_c99b0f49a/a-deep-dive-on-how-backend-servers-handles-http-connections-1jom</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Imagine this scenario: you’ve built a backend application, tested it on your &lt;a href="http://localhost/" rel="noopener noreferrer"&gt;localhost&lt;/a&gt;, and the requests are blazing fast with minimal resource usage. But when the server load increases, requests slow down or even start to time out. You’re left scratching your head — is the problem in the backend logic, the programming language, the database queries, the hosting machine, or the reverse proxy?&lt;/p&gt;

&lt;p&gt;In this article, we’ll take a deep dive into &lt;strong&gt;how backend HTTP requests are executed under the hood&lt;/strong&gt;. By understanding what your server is actually doing, you’ll be better equipped to identify performance bottlenecks.&lt;/p&gt;




&lt;h1&gt;
  
  
  How TCP Connections Are Established
&lt;/h1&gt;

&lt;p&gt;We won’t go into too much depth here, just enough lingo to follow the rest of the article. (If you’d like a deep-dive on TCP itself, drop a comment and I’ll write a separate post.)&lt;/p&gt;

&lt;p&gt;TCP uses a three-way handshake:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SYN&lt;/strong&gt;: the client sends a sync request to the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SYN/ACK&lt;/strong&gt;: the server acknowledges and responds with its own sync request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACK&lt;/strong&gt;: the client acknowledges, and both sides are in sync.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point, the TCP connection is established.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Why TCP?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because HTTP/1.1 and HTTP/2 — the most widely used versions — are built on top of TCP. (HTTP/3 uses QUIC, a different protocol, which we won’t cover here.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbw3g2cu55gaiwh5h46k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbw3g2cu55gaiwh5h46k.png" alt=" " width="409" height="224"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  The Kernel’s Role
&lt;/h1&gt;

&lt;p&gt;When you send an HTTP request to a server, the Linux kernel manages it using two queues:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The SYN Queue
&lt;/h3&gt;

&lt;p&gt;This queue holds &lt;strong&gt;half-open connections&lt;/strong&gt;. After the server replies with &lt;code&gt;SYN/ACK&lt;/code&gt; but before the client’s final &lt;code&gt;ACK&lt;/code&gt;, the connection sits here.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Accept Queue
&lt;/h3&gt;

&lt;p&gt;Once the handshake is complete, the connection is moved to the &lt;strong&gt;accept queue&lt;/strong&gt;. At this point, the kernel is done — it’s up to the backend application to pick it up using the &lt;code&gt;accept()&lt;/code&gt; syscall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important detail&lt;/strong&gt;: if the &lt;strong&gt;accept queue is full&lt;/strong&gt;, new connections will be dropped (or reset). This is controlled by the kernel parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/net/core/somaxconn
-&amp;gt; 128
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(default is often 128). Increasing this can help servers under heavy load.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Another detail&lt;/strong&gt;: if the ack from clients takes too long the kernel automatically drops the connections&lt;/p&gt;




&lt;h1&gt;
  
  
  The Backend Application’s Role
&lt;/h1&gt;

&lt;p&gt;After a connection enters the accept queue, the application must call the &lt;code&gt;accept()&lt;/code&gt; syscall to start handling it.&lt;/p&gt;

&lt;p&gt;Your application’s &lt;strong&gt;concurrency performance&lt;/strong&gt; depends on how quickly it can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accept new connections&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execute requests&lt;/strong&gt; without blocking other connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhym5xuse8dj0mw4npw17.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhym5xuse8dj0mw4npw17.png" alt=" " width="533" height="571"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  How Different Backends Handle Connections
&lt;/h1&gt;

&lt;p&gt;We need to distinguish two phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accepting connections&lt;/strong&gt;: how the server calls &lt;code&gt;accept()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Executing connections&lt;/strong&gt;: how the HTTP request itself is processed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Node.js
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single-threaded&lt;/strong&gt; for both accepting and executing requests.&lt;/li&gt;
&lt;li&gt;Famous for &lt;strong&gt;non-blocking I/O&lt;/strong&gt;. While a request is waiting for an I/O operation (like a DB query), Node.js can accept new connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Problem: if a request is &lt;strong&gt;CPU-bound&lt;/strong&gt; (e.g., a huge loop or sync file read), the event loop blocks. Other requests won’t even be logged until the CPU task finishes.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LIMIT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;_000_000_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;LIMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blocking&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Blocking request received&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Result is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call &lt;code&gt;/blocking&lt;/code&gt; twice in quick succession: the second request won’t even log until the first finishes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgji7pv582mmkr284amf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgji7pv582mmkr284amf.png" alt=" " width="249" height="557"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Go
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Accepts connections on the main thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immediately spawns a goroutine&lt;/strong&gt; for each request, leaving the main thread free to keep accepting new ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the &lt;code&gt;net/http&lt;/code&gt; docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Serve accepts incoming connections, creating a new service goroutine for each. The service goroutines read requests and then call the handler to reply.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This model balances simplicity with concurrency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkuo2ydn5pyw66vf0v8mq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkuo2ydn5pyw66vf0v8mq.png" alt=" " width="697" height="621"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Python (WSGI servers like Gunicorn/uWSGI)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Concurrency depends on &lt;strong&gt;workers&lt;/strong&gt; (threads or processes).&lt;/li&gt;
&lt;li&gt;When a connection is accepted, it’s assigned to a worker.&lt;/li&gt;
&lt;li&gt;Multiple workers prevent one slow request from blocking others.&lt;/li&gt;
&lt;li&gt;CPU-bound workloads still block individual workers, so scaling often means running &lt;strong&gt;multiple processes&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  PHP (Apache/Nginx + PHP-FPM)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The web server (Apache or Nginx) handles connection management.&lt;/li&gt;
&lt;li&gt;Each request is passed to a PHP worker (via mod_php or PHP-FPM).&lt;/li&gt;
&lt;li&gt;Requests run in &lt;strong&gt;isolated processes&lt;/strong&gt;, so one request won’t block another — but each worker is heavier than a lightweight goroutine or async event loop.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Others (quick mentions)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Java (Servlets, Tomcat, Netty)&lt;/strong&gt;: thread-per-request (Tomcat) or event-driven (Netty).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust (Tokio, Actix)&lt;/strong&gt;: async event loops, similar to Node.js but highly optimized.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Useful Commands
&lt;/h1&gt;

&lt;p&gt;Play around with these to observe queues and connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/net/ipv4/tcp_max_syn_backlog   &lt;span class="c"&gt;# max SYN queue length&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/net/core/somaxconn             &lt;span class="c"&gt;# max accept queue length&lt;/span&gt;
ss &lt;span class="nt"&gt;-tln&lt;/span&gt;                                      &lt;span class="c"&gt;# show sockets + queue info&lt;/span&gt;
netstat &lt;span class="nt"&gt;-anp&lt;/span&gt;                                 &lt;span class="c"&gt;# legacy alternative&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For load testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ab &lt;span class="nt"&gt;-n&lt;/span&gt; 1000 &lt;span class="nt"&gt;-c&lt;/span&gt; 100 http://localhost:3000/
wrk &lt;span class="nt"&gt;-t12&lt;/span&gt; &lt;span class="nt"&gt;-c400&lt;/span&gt; &lt;span class="nt"&gt;-d30s&lt;/span&gt; http://localhost:3000/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;By now, you should have a clearer picture of what happens when a client connects to your backend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The kernel manages the handshake and queues.&lt;/li&gt;
&lt;li&gt;The backend application must efficiently &lt;code&gt;accept()&lt;/code&gt; and execute connections.&lt;/li&gt;
&lt;li&gt;Different runtimes handle this differently: event loops, goroutines, workers, or processes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key takeaway: performance issues often aren’t just about your code or your database queries — they can stem from &lt;strong&gt;queue limits&lt;/strong&gt;, &lt;strong&gt;blocking workloads&lt;/strong&gt;, or how your runtime handles concurrency.&lt;/p&gt;

&lt;p&gt;In part two, we’ll look at how the kernel manages &lt;strong&gt;sending responses&lt;/strong&gt; using the send/receive queues (&lt;code&gt;sendq&lt;/code&gt; and &lt;code&gt;recvq&lt;/code&gt;).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>WebSocket Authentication in NestJS: Handling JWT and Guards</title>
      <dc:creator>Mouloud hasrane</dc:creator>
      <pubDate>Sat, 09 Aug 2025 12:16:19 +0000</pubDate>
      <link>https://dev.to/mouloud_hasrane_c99b0f49a/websocket-authentication-in-nestjs-handling-jwt-and-guards-4j27</link>
      <guid>https://dev.to/mouloud_hasrane_c99b0f49a/websocket-authentication-in-nestjs-handling-jwt-and-guards-4j27</guid>
      <description>&lt;p&gt;When working with WebSockets in NestJS using gateways, developers quickly encounter a fundamental challenge: traditional authentication guards don't work seamlessly with JWT tokens, especially short-lived ones. Unlike HTTP requests where each call can be independently authenticated, WebSocket connections are persistent, creating unique authentication requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Problem
&lt;/h2&gt;

&lt;p&gt;NestJS guards are designed for request-response cycles, but WebSockets maintain long-lived connections. If you're using short-lived JWT tokens and attempt to verify authentication on each message, the token will eventually expire mid-connection, breaking the user experience. This leaves developers with a few viable approaches.&lt;br&gt;
Guards Are more Usefull in Ws context With AuthZ (Authorization) like RBAC (message spececif) &lt;/p&gt;
&lt;h2&gt;
  
  
  Authentication Strategies
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Session-Based Authentication
&lt;/h3&gt;

&lt;p&gt;The most straightforward approach is using session-based authentication, where guards can function normally since sessions persist across the connection lifecycle. However, this approach may not suit all architectural requirements, particularly in stateless or distributed systems.&lt;/p&gt;
&lt;h3&gt;
  
  
  Long-Lived Token Method
&lt;/h3&gt;

&lt;p&gt;One workaround is generating a long-lived token specifically for WebSocket connections during the initial handshake. This token gets attached to the client and acknowledged, allowing the connection to remain authenticated for its entire duration. While effective, this approach requires careful token management and potential security considerations around longer token lifespans.&lt;/p&gt;
&lt;h3&gt;
  
  
  Normal access tokens - refresh Tokens
&lt;/h3&gt;

&lt;p&gt;This method is basically trying to recreate the flow of normal http access -refresh tokens jwt authentication , but Emitting a refresh token event to the server on  Unauthorized Ws Exception and then waiting for an ack from the server with the new access and refresh tokens  , this can work sure ! , but it can also cause problems at scale (parsing the jwt on each websocket message, connections management ...etc) , and requires more client side configuration. &lt;/p&gt;
&lt;h3&gt;
  
  
  Handshake-Only Verification
&lt;/h3&gt;

&lt;p&gt;The most common approach is to verify authentication only during the WebSocket handshake. Once the connection is established and authenticated, subsequent messages are trusted. This balances security with practicality, though it requires careful connection management.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Gateway Architecture Challenge
&lt;/h2&gt;

&lt;p&gt;Here's where NestJS WebSocket implementation presents an interesting architectural challenge. When you have multiple gateways operating on the same namespace, any connection initialization logic defined in one gateway applies to all gateways in that namespace (this is not anywhere on the docs this was found with trial and error), and we are going to use that to in our favor to create a centralized Auth logic handler for our gatewatys&lt;/p&gt;
&lt;h2&gt;
  
  
  The Gateway Extension Pattern
&lt;/h2&gt;

&lt;p&gt;The solution lies in creating a structured hierarchy of gateway classes that properly separate connection management from business logic.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Create a Base WebSocket Manager
&lt;/h3&gt;

&lt;p&gt;First, create a base gateway class (commonly named &lt;code&gt;WSManager&lt;/code&gt; or &lt;code&gt;WebSocketManager&lt;/code&gt;) that handles all connection-related logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WSManager&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnGatewayInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnGatewayConnection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//Use Property based injection on the parent class to avoid passing them on the sub-classes constructor&lt;/span&gt;
&lt;span class="c1"&gt;//class ref is the key of the provider change this if you have custom provider defenition &lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AuthenticationService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt;  &lt;span class="nx"&gt;authService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;AuthenticationService&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;handleConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle authentication logic here&lt;/span&gt;
    &lt;span class="c1"&gt;// Verify JWT on handshake&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handshake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validateToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
          &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Set up client metadata&lt;/span&gt;
    &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;afterInit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Server initialization logic&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ps&lt;/strong&gt;:you can add the @webSocketGateway() decorator to this class if you have the default namespace and you don't want to extend this on the gateways related to it &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Extend for Specific Functionality
&lt;/h3&gt;

&lt;p&gt;For each specific WebSocket feature (notifications, chat, real-time updates, etc.), create dedicated gateways that extend the base manager:&lt;br&gt;
so what will happen here  is the notification Gateway will extend the WsManger implementation of the handleConnection from the WsManager&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;WebSocketGateway&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/notifications&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificationGateway&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;WSManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;SubscribeMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscribe-to-notifications&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;handleNotificationSubscription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Notification-specific logic&lt;/span&gt;
    &lt;span class="c1"&gt;// Connection is already authenticated via parent class&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important Note
&lt;/h3&gt;

&lt;p&gt;If you  have a custom logic of the after Init other than Authentication Something like &lt;strong&gt;RBAC&lt;/strong&gt; or Rooms joining logic , you can implement the OnGatewayConnection on the intended NameSpace while keeping the same logic as before by Calling&lt;br&gt;
&lt;br&gt;
  &lt;code&gt;super.handleConnection()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;WebSocketGateway&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificationGateway&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;WSManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;chatService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;ChatService&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;span class="c1"&gt;//Important here to call super for dependency injection to work&lt;/span&gt;
&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="nf"&gt;handleConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;//Available now since it was set on the base Class&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canConnect&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chatService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;canConnect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;canConnect&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;//Custom Exception&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;New&lt;/span&gt; &lt;span class="nc"&gt;ConnectionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cannot connect to the chat service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;room&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;extractRoomfromHandShake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handshake&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;room&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;SubscribeMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sendMessage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;handleSendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Connection is already authenticated via parent class and the user in the correct room(s)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The gateway extension pattern solves the fundamental challenge of WebSocket authentication in NestJS by separating connection management from business logic. This approach provides:&lt;/p&gt;

&lt;p&gt;Centralized Authentication: All connection security logic in one reusable class&lt;br&gt;
Clean Architecture: Business logic gateways focus on their specific domain&lt;br&gt;
Maintainability: Changes to authentication flow only require updates in one location&lt;br&gt;
Scalability: Easy to add new WebSocket features without duplicating authentication code&lt;/p&gt;

&lt;p&gt;While NestJS WebSocket authentication presents unique challenges compared to traditional REST endpoints, understanding the connection lifecycle and leveraging proper inheritance patterns creates a robust, maintainable solution that scales with your application's needs.&lt;br&gt;
Remember to always validate your authentication approach based on your specific security requirements and consider implementing additional measures like rate limiting and connection monitoring for production environments.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mastering Microservices with NestJS: A Practical Guide to Scalable Architectures</title>
      <dc:creator>Mouloud hasrane</dc:creator>
      <pubDate>Thu, 20 Feb 2025 00:35:12 +0000</pubDate>
      <link>https://dev.to/mouloud_hasrane_c99b0f49a/building-scalable-microservices-with-nestjs-5d16</link>
      <guid>https://dev.to/mouloud_hasrane_c99b0f49a/building-scalable-microservices-with-nestjs-5d16</guid>
      <description>&lt;p&gt;Ever wondered how tech giants like Netflix, Uber, and Amazon handle millions of requests without breaking a sweat? The secret lies in microservices architecture—a game-changing approach that makes applications more scalable, resilient, and easier to maintain.&lt;/p&gt;

&lt;p&gt;In this guide, we'll demystify microservices, explore their benefits, and walk through a hands-on implementation using NestJS and RabbitMQ. Ready to level up your backend skills? Let’s dive in! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 Why NestJS?
&lt;/h2&gt;

&lt;p&gt;One of the standout features of NestJS is its native support for microservices architecture. When using microservices in NestJS, you can still leverage decorators, guards, pipes, interceptors, and other features found in a traditional monolithic NestJS app.&lt;/p&gt;

&lt;p&gt;Before we jump into the code, let’s break down what microservices are and why they are so powerful.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️   What Are Microservices?
&lt;/h2&gt;

&lt;p&gt;In a typical monolithic architecture, a single server handles all requests, processes the logic, and returns a response.&lt;/p&gt;

&lt;p&gt;In contrast, a microservices architecture breaks down an application into multiple independent services, each handling a specific piece of logic.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Instead of one big server doing everything, we have multiple smaller services (often called microservices) working together.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  🛠️ Why Microservices?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  ✅  Separation of Concerns &amp;amp; Decoupling:
&lt;/h3&gt;

&lt;p&gt;Each microservice is responsible for a specific aspect of the application, making it easier to scale and debug.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✅   Fault Tolerance:
&lt;/h3&gt;

&lt;p&gt;If one service goes down, only that part of the app is affected, not the entire system.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✅ Scalability &amp;amp; Performance:
&lt;/h3&gt;

&lt;p&gt;Since services are independent, they can be scaled individually based on demand.&lt;/p&gt;

&lt;p&gt;Now after that, you might Ask : &lt;em&gt;Now, you might ask: how do these services communicate with each other?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ande we need to introduce the concept of a transport layer, you can imagine it for now as the route or the bridge that links all of the services together it sends data across multiple services :fmo us transport layers are  :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TCP&lt;/li&gt;
&lt;li&gt;RMQ&lt;/li&gt;
&lt;li&gt;BullMq&lt;/li&gt;
&lt;li&gt;Grpc
and a lot more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcugtm5h0vnn8et9li3u0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcugtm5h0vnn8et9li3u0.png" alt="Communication Example" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is cool about nests that is allows you to use your preferred transport layer from the multiple ones it offers and you can easily change it in the configuration without changing the code later (say you are using Tcp and after a while, you wanted to  switch over to a message queue like RMQ you just have to change it in the configuration of the module without changing anything in the code)&lt;/p&gt;

&lt;p&gt;Before we jump into coding (I know it took too long but this is not your average code tutorial blog we need to understand what exactly each piece of code does when we write it) we need to discuss one last thing that is the types of microservices, in this context ,we are focusing on types regarding how are req-res are handled and we will focus on 2 types:&lt;/p&gt;
&lt;h2&gt;
  
  
  Request-response (Message pattern):
&lt;/h2&gt;

&lt;p&gt;Here we send a message( which is just a piece of data) over to the right service over a transport layer, and then wait for it to return a response to use &lt;/p&gt;
&lt;h2&gt;
  
  
  Event-based
&lt;/h2&gt;

&lt;p&gt;Here we are also sending a message or in this case, it is called an event but we don't actually expect or wait for a response instead side effects are just happening in the appropriate service(s) &lt;strong&gt;In most cases events are unidirectional meaning that the data only goes in one way&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9o5s85mxuxk9wtejya3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9o5s85mxuxk9wtejya3.png" alt="Event vs Req-Res" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;now that we have a basic understanding of what micro services architecture is all about let's dive into how to implement it using nestJs&lt;/p&gt;
&lt;h2&gt;
  
  
  Example of A micro Services System
&lt;/h2&gt;

&lt;p&gt;here is what a micro Services system look like &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc4gpk6xebh8rdh22jnbt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc4gpk6xebh8rdh22jnbt.png" alt=" " width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  NestJs Implementation:
&lt;/h2&gt;

&lt;p&gt;We will try to build a simple e-commerce example to showcase microServices in nests&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;First we Create a normal nests application this application is often called the producer because unlike other nodes it is an HTTP app that is responsible for getting the requests and sending them to the appropriate service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;then  we need to install  the microServices module&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm i &lt;span class="nt"&gt;--save&lt;/span&gt; @nestjs/microservices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 . Install the transport layer here I'm using Rabbit mq feel free to use anyone you like (check the documentation for supported Transport   layers)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm i &lt;span class="nt"&gt;--save&lt;/span&gt; amqplib amqp-connection-manager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We define a simple dto for validation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IsEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IsNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IsString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;class-validator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;orderDto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsEmail&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsNumber&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we register our services inside the app Module or  the feature module if you want better separation,  using the microservices module that we just downloaded here we will only use the payment and orders service&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OrdersController&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./orders.controller&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ClientsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Transport&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/microservices&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

 &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;ClientsModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ORDER_SERVICE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RMQ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;URLs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amqp://localhost:5672&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;order_queue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;queueOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;durable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Make the queue persistent&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="c1"&gt;// Specify an exchange&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;]),&lt;/span&gt;
  &lt;span class="nx"&gt;ClientsModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYMENT_SERVICE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RMQ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;URLs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amqp://localhost:5672&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payment_queue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;queueOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;durable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Make the queue persistent&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="c1"&gt;// Specify an exchange&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;]),&lt;/span&gt;

  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;OrdersController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;OrdersService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I'm using RabbitMq which is a powerful message queue &lt;br&gt;
 &lt;strong&gt;a message queue&lt;/strong&gt;: is a transport layer that uses the FIFO Data structure and holds the messages in a queue until the first message gets processed by the  consumer (service), what is cool about it is that if the consumer is down it will wait until it is up again (unlike tcp for example which if the service is down the message will just be lost)&lt;/p&gt;

&lt;p&gt;Here is a simple controller that handles 2 requests&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* eslint-disable prettier/prettier */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OrdersService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./orders.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;orderDto&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./orderDto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orders&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;read&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;only&lt;/span&gt; &lt;span class="nx"&gt;ordersService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OrdersService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nc"&gt;OrderAdded&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;orderDto&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ordersService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/pay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;payOrder&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;orderDto&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ordersService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handle&lt;/span&gt; &lt;span class="nf"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is the service&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;orderDto&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./orderDto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ClientProxy&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/microservices&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ORDER_SERVICE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;RSERVICE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;ClientProxy&lt;/span&gt;&lt;span class="p"&gt;,@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYMENT_SERVICE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;PAYMENTQueue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;ClientProxy&lt;/span&gt;  &lt;span class="p"&gt;){}&lt;/span&gt;
  &lt;span class="nf"&gt;handleOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;orderDto&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RSERVICE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ORDER_PLACED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ORDER ADDED!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="nx"&gt;handle&lt;/span&gt; &lt;span class="nf"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;orderDto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PAYMENTQueue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYMENT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYMENT DONE!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is where the magic happens first we Inject services registered earlier in the module and then we emitting events the first String in the emit method is the event pattern which is how the service now what logic to execute and the second param is the payload which is the actual data that the service needs to work with.&lt;br&gt;
here we are using .emit because we are using event-based architecture &lt;br&gt;
if you want to use a message you just use .send instead&lt;/p&gt;

&lt;p&gt;And then we need to create another nest application which is the service itself here is how to define the main of the app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NestFactory&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Transport&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/microservices&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;NestFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createMicroservice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AppModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RMQ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;URLs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amqp://localhost:5672&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;order_queue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;queueOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;durable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;what changes that we create a microService instead of a nest application and then we define the appropriate transport layer that this service uses to communicate with the producer&lt;br&gt;
 and here is to define the controller to handle upcoming events&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OrdersService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./orders.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EventPattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RmqContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/microservices&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OrderDto&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./orderDto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orders&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;ordersService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OrdersService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;EventPattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ORDER_PLACED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;handleOrders&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Payload&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OrderDto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Ctx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RmqContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ordersService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;note that the Event Pattern  is the same one we sent Earlier &lt;br&gt;
here we get Acces to the payload that we send and the Excution context which contains some metadata that are out of the scope of this article &lt;br&gt;
what cool now is that we can register another Service inside this service and send events to it as well like we're doing here in the service&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ClientProxy&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/microservices&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OrderDto&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./orderDto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYMENT_SERVICE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;paymentClient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ClientProxy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="nf"&gt;handleOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OrderDto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PROCESSING ORDER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SENDING ORDER TO PAYMENT SERVICE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paymentClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PAYMENT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and Payment Client is another service built just like this one &lt;/p&gt;

&lt;p&gt;In this article, we explored how to build a microservices architecture using NestJS and RabbitMQ. We discussed the benefits of microservices, such as scalability, fault tolerance, and separation of concerns, and demonstrated how NestJS simplifies inter-service communication.&lt;/p&gt;

&lt;p&gt;By leveraging RabbitMQ as a message broker, we ensured reliable, asynchronous communication between services, making our system more resilient and efficient. The flexibility of NestJS also allows us to switch transport layers easily, giving us the freedom to adapt to different use cases.&lt;/p&gt;

&lt;p&gt;As you continue building microservices, consider factors like service discovery, monitoring, and security to enhance your system further. Experiment with different transport layers, and explore tools like Kubernetes for orchestration. Microservices can be complex, but with the right tools and architecture, they can unlock powerful scalability and maintainability for your applications. 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding Replication and Sharding in System Design</title>
      <dc:creator>Mouloud hasrane</dc:creator>
      <pubDate>Wed, 29 Jan 2025 00:11:59 +0000</pubDate>
      <link>https://dev.to/mouloud_hasrane_c99b0f49a/understanding-replication-and-sharding-in-system-design-50o</link>
      <guid>https://dev.to/mouloud_hasrane_c99b0f49a/understanding-replication-and-sharding-in-system-design-50o</guid>
      <description>&lt;p&gt;When discussing system design, terms like sharding, partitioning, replication, and master-slave relationships frequently come up. If these concepts seem confusing, don't worry! This article will clarify the differences between replication and sharding to help you build a solid foundation in distributed database systems.&lt;br&gt;
ps: images are from building data intensive systems book be sure to check it out&lt;/p&gt;

&lt;h2&gt;
  
  
  Replication
&lt;/h2&gt;

&lt;p&gt;Replication involves creating multiple instances of a database that contain the same data as the main instance. This allows requests to be distributed among replicas, improving system performance and availability. But how do we decide which requests go to which instance? Replication can be categorized into different types, but in practice, two are most commonly used:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Master-Slave Replication (Leader-Follower Replication)
&lt;/h3&gt;

&lt;p&gt;In this model, a leader (master) database handles both read and write operations, while followers (slaves) handle only read operations. Any write operation made to the leader is replicated to the followers, either synchronously or asynchronously (we’ll discuss these approaches in detail in a future article).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82n9eygo5ywm1a9dc7lz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82n9eygo5ywm1a9dc7lz.png" alt="Leader follower replication" width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is this useful?&lt;/p&gt;

&lt;p&gt;Most systems are read-heavy rather than write-heavy, meaning they perform far more read operations than writes. By distributing read queries to multiple followers, we can significantly reduce the load on the leader instance, improving performance and scalability.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Master-Master Replication (Leader-Leader Replication)
&lt;/h3&gt;

&lt;p&gt;Now, imagine our system has grown to the point where we need multiple data centers worldwide to minimize latency. If we rely on leader-follower replication, choosing a single leader across all data centers would lead to slow write operations for users far from that leader.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s6192uy5s487887bm4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s6192uy5s487887bm4h.png" alt="Leader-leader replication" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With leader-leader replication, each data center has its own leader. When a write operation is performed at one leader, it is propagated to all other leaders, which then replicate it to their followers, in other words each leader acts as a follower to the leader that just got the write operations and then as a leader to send the new data to his followers&lt;br&gt;
Challenges:&lt;/p&gt;

&lt;p&gt;While this approach improves performance and fault tolerance, it introduces challenges such as write conflicts, where two leaders handle conflicting writes at the same time. Handling such conflicts requires careful resolution strategies, such as conflict-free replicated data types (CRDTs) or last-write-wins (LWW) mechanisms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sharding
&lt;/h2&gt;

&lt;p&gt;Unlike replication, which creates copies of the same database, sharding (also called partitioning) splits the database into smaller subsets, called shards, each containing a portion of the data. This allows for better scalability by distributing requests across multiple shards.&lt;br&gt;
How do we determine which shard a request should go to?&lt;/p&gt;

&lt;p&gt;Two common techniques for sharding are:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Key Range Sharding
&lt;/h3&gt;

&lt;p&gt;In this approach, data is divided into shards based on a predefined range of values. Think of it like an encyclopedia where different volumes contain different alphabetic sections of words.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycviyfa5wa0ia2dfuwgb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycviyfa5wa0ia2dfuwgb.png" alt="Key range sharding" width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example: User IDs from 1–1000 go to Shard A, 1001–2000 go to Shard B, and so on.&lt;/p&gt;

&lt;p&gt;Advantage: Simple to implement.&lt;/p&gt;

&lt;p&gt;Disadvantage: Can lead to hot spots—if a specific range receives more requests than others, that shard will become overloaded.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Hash-Based Sharding
&lt;/h3&gt;

&lt;p&gt;Here, a hash function is applied to a data attribute (e.g., User ID) to determine which shard should store the data. A well-designed hash function distributes data evenly across shards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu4iih2p34ts40hx8glf3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu4iih2p34ts40hx8glf3.png" alt="hash based sharding" width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;say for example  If hash(UserID) % 3 == 0, the request is sent to Shard A; if hash(UserID) % 3 == 1, it goes to Shard B, and so on.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Advantage: Ensures even distribution and prevents hot spots.

Disadvantage: Can make it difficult to perform range queries, as data is spread across multiple shards unpredictably.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Rebalancing Shards
&lt;/h2&gt;

&lt;p&gt;As data grows and system demands change, sharded databases must be rebalanced to maintain efficiency. This involves redistributing data and queries among nodes while minimizing disruptions. Rebalancing is crucial to:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prevent overload on specific shards.

Maintain system availability for read/write operations.

Minimize data movement to reduce network and disk I/O overhead.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We will discuss different rebalancing strategies and common pitfalls in a future article.&lt;/p&gt;

&lt;h2&gt;
  
  
  why bother using any of those techniques :
&lt;/h2&gt;

&lt;p&gt;as the system scales up or single instance database will not be able to handle all of the request efficiently, which will cause reduce the response time   , that will affect the user experience which in of itself will affect our sales and user count, you  may think no problem let's just get a stronger pc that can handle those request , but as we keep scaling up the hardware will be costly and hard to find (you'll reach a point when you have the most powerful disk out there to run you db on ),for that reason we use this strategies to keep or response time and overall experience smooth no matter how much our app scales.&lt;br&gt;
Final Thoughts&lt;/p&gt;

&lt;p&gt;Now that you have a fundamental understanding of replication and sharding, you can explore their trade-offs and edge cases in greater detail. Each technique has its own benefits and challenges, and the best approach depends on your system’s requirements.&lt;/p&gt;

&lt;p&gt;Stay tuned for more in-depth articles on advanced replication strategies, handling conflicts in distributed databases, and optimizing sharding techniques!&lt;/p&gt;

&lt;p&gt;Happy learning! 🚀&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>softwareengineering</category>
      <category>backend</category>
      <category>database</category>
    </item>
  </channel>
</rss>
