<?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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2362259%2F8a1ec6f4-a18f-4fe2-be54-6ca950d8b4d3.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>How a Simple Screen Share Feature Turned Into a WebRTC Rabbit Hole</title>
      <dc:creator>Mouloud hasrane</dc:creator>
      <pubDate>Mon, 13 Jul 2026 12:47:54 +0000</pubDate>
      <link>https://dev.to/mouloud_hasrane_c99b0f49a/how-a-simple-screen-share-feature-turned-into-a-webrtc-rabbit-hole-123j</link>
      <guid>https://dev.to/mouloud_hasrane_c99b0f49a/how-a-simple-screen-share-feature-turned-into-a-webrtc-rabbit-hole-123j</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I've spent way too much time trying to come up with some generic introduction for this story, but then I realized none of you probably want to read that anyway. So instead, I'll just jump straight into the story—which is why you're here in the first place.&lt;/p&gt;




&lt;h2&gt;
  
  
  The day I received the requirements
&lt;/h2&gt;

&lt;p&gt;The story begins when I received the requirements for a new feature that allows Teachers to share their presentation to review slides before the Lecture begins, so we would have teachers aids using the web version and seeing a screenshare from the main pc powerpoint, at first I thought maybe we can use HLS or RTMP for this and be okay with the 3 seconds delay that it has, but then I continued reading the ticket, we also needed the user to move to the next and previous slides via the web application, which immediately threw my initial idea out of the window. This is because if the user needs to interact with the application there is no way it will be usable without almost immediate feedback.&lt;/p&gt;

&lt;p&gt;Since we needed to show this to the client quickly we had 2 weeks to implement this feature, so before I did anything, I stopped and started drafting a simple design doc, which besides the fancy name was really just a document with my raw notes taken from research and comparisons between different solutions.&lt;/p&gt;

&lt;p&gt;After spending some time doing research and looking into different architectures and engineering blogs from companies like Twitch, Slack and Discord, I narrowed the possibilities down to four common architectures used for this type of use case.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Options
&lt;/h2&gt;

&lt;h3&gt;
  
  
  P2P Mesh
&lt;/h3&gt;

&lt;p&gt;This approach revolved around a user establishing &lt;code&gt;WebRTC&lt;/code&gt; connections with every other user in the room. Besides being difficult to manage in terms of connections and sessions, it had one fatal flaw: network and CPU overhead.&lt;/p&gt;

&lt;p&gt;If we had twenty users in the room, every participant would maintain nineteen separate peer connections while sending nineteen streams, quickly consuming both CPU and bandwidth.&lt;/p&gt;




&lt;h3&gt;
  
  
  MCU (Multipoint Control Unit)
&lt;/h3&gt;

&lt;p&gt;Going back into server-client architectures, an &lt;code&gt;MCU&lt;/code&gt; attempts to centralize media by ingesting streams from producers, multiplexing them together, and then sending the processed result to consumers.&lt;/p&gt;

&lt;p&gt;This makes connection management significantly easier since every client only sends and receives a single stream.&lt;/p&gt;

&lt;p&gt;The downside is that multiplexing introduces additional latency while also making the server responsible for expensive media processing. Since our entire requirement revolved around low latency, this wasn't the direction we wanted to take.&lt;/p&gt;




&lt;h3&gt;
  
  
  SFU (Selective Forwarding Unit)
&lt;/h3&gt;

&lt;p&gt;This was the most promising option.&lt;/p&gt;

&lt;p&gt;Like an MCU, clients only connect to a central server, but instead of processing the media, the server simply forwards streams from producers to consumers.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;much lower latency,&lt;/li&gt;
&lt;li&gt;significantly lower server CPU usage,&lt;/li&gt;
&lt;li&gt;far better scalability than a mesh network.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given our requirements, this immediately became the strongest candidate.&lt;/p&gt;




&lt;h3&gt;
  
  
  Hybrid (Mesh + SFU)
&lt;/h3&gt;

&lt;p&gt;Another common approach is dynamically switching between Mesh and SFU depending on participant count or network conditions.&lt;/p&gt;

&lt;p&gt;In theory this offers the best of both worlds.&lt;/p&gt;

&lt;p&gt;In practice, it also means maintaining two completely different implementations.&lt;/p&gt;

&lt;p&gt;Given our timeline, this was quickly ruled out.&lt;/p&gt;




&lt;h3&gt;
  
  
  Custom WebRTC implementation
&lt;/h3&gt;

&lt;p&gt;Another approach worth mentioning is modifying WebRTC itself to fit the use case.&lt;/p&gt;

&lt;p&gt;Discord, for example, has invested heavily in custom WebRTC optimizations, but doing something similar requires an entire engineering team working at a much lower level than what was realistic for our project.&lt;br&gt;
While not realistic for most teams , it can be still a fun read &lt;a href="https://discord.com/blog/how-discord-handles-two-and-half-million-concurrent-voice-users-using-webrtc" rel="noopener noreferrer"&gt;discord&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The MediaSoup Journey
&lt;/h2&gt;

&lt;p&gt;After sending over the architecture document and discussing the trade-offs, we settled on the SFU approach.&lt;/p&gt;

&lt;p&gt;The next question became:&lt;/p&gt;

&lt;p&gt;How do we actually build one?&lt;/p&gt;

&lt;p&gt;We weren't going to implement an SFU from scratch, so I started looking for existing libraries.&lt;/p&gt;

&lt;p&gt;The first thing that caught my attention was &lt;code&gt;MediaSoup&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It was extremely popular, battle-tested, and had a very well-designed architecture, so naturally it became the first solution I experimented with.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Express wrapper and why
&lt;/h3&gt;

&lt;p&gt;So after reading the docs thoroughly  and understanding the all the components well I realized something very important , media soup has some class clients that we need to track their state in memory , and as we all know &lt;code&gt;State is evil&lt;/code&gt;, so there was no way I add this to the core api server , so I decided to create a separate express server that will act as a wrapper around media soup and handle all the state management and client connections and sessions , this way we can keep the core api server stateless and also we can easily scale the express server if needed without affecting the core api server , I also made this wrapper open source since I thought it might be useful for other people who want to use mediaSoup &lt;br&gt;
and expirement with it , it is still not a production ready yet! since there are some few stuff missing example of that can be  implementing horizonatl scaling (which is not as scary as it sounds when hearing statefull server since mediaSoup already has a mechanism to deal with this in place), all contributions are welcome &lt;a href="https://github.com/mouloud240/media-Soup-Express" rel="noopener noreferrer"&gt;MediaSoup wrapper&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The web proof of concept
&lt;/h3&gt;

&lt;p&gt;it took just few hours to have the media soup up and running , so now I need it to test how everything works together , so I created simple web application that just connects to the api and starts a screenshare session while other clients , watch that screenshare , I tweaked the api a bit , modified ips stuff , but eventually it worked like a charm , better thatn I even Imagined , the delay was very low and the quality was great , I was very happy with the results and I thought that we are good to go and start working on the flutter library and integration with the core api server .&lt;/p&gt;

&lt;h3&gt;
  
  
  The Flutter library modification journey
&lt;/h3&gt;

&lt;p&gt;Well ..., after the proof of concept was done , I went looking for flutter libraries that can work with media soup , and guess what ? the only libraray I found had the last commits 2 years ago at that time , but I still was optimistic since it is mostly the same protocol and the same architecure , how bad can it be right?, so with my previous experience in flutter I ran the app locally added the libraray , integrated with our server and started testing , and ironicaly  media soup V3 decided to change the way that it handles dtls handshakes and session management , you can imagine how that went , but still I said how bad can it be (spoilers alert it was very bad), I spent a week trying to tweak the library, going deeper and deeper into the layer of abstraction and down the rabit hole as well , until I finally gave up and said that this is not the right solution for us , we need to look for other solutions that are more compatible with flutter and have better support for it , so I went back to the drawing board and started looking for other solutions that can fit out solutions .&lt;br&gt;
Also I already wasted  4-5 days trying to do this so for the next parts I had to move quickly&lt;/p&gt;




&lt;h2&gt;
  
  
  Searching for the correct tool (2 days left)
&lt;/h2&gt;

&lt;p&gt;After spending almost a week trying to make MediaSoup work with Flutter, it became clear that continuing wasn't the right decision.&lt;/p&gt;

&lt;p&gt;With only two days left before the demo, I went back to researching alternatives.&lt;/p&gt;

&lt;p&gt;After another long night of searching I narrowed the remaining candidates down to three.&lt;/p&gt;

&lt;h3&gt;
  
  
  Janus
&lt;/h3&gt;

&lt;p&gt;Janus is a very powerfull battle tested sfu that many big companies used including slack when they first launched their calls feature back on 2016 , it has a very good documentation but it also had a lot of features and a lot of integration to setup which made it very hard for use to fully understand the documentation and how to integrate it in only 2 days.&lt;/p&gt;

&lt;h3&gt;
  
  
  MediaMTX
&lt;/h3&gt;

&lt;p&gt;MediaMtx is a promising  famous repo with over 18k stars on github , however internally it is not an sfu per say but  a Media server and proxy so it is similar to an &lt;code&gt;MCU&lt;/code&gt; rather than an &lt;code&gt;SFU&lt;/code&gt;, tho it had a good features I decided to move away from it in the meantime &lt;/p&gt;

&lt;h3&gt;
  
  
  SRS (Simple Realtime Server)
&lt;/h3&gt;

&lt;p&gt;SRS is a simple and easy to use streaming server that supports variety of protocols which includes (hls, rtmp , webrtc, sfu  , mcu ,whip-whep...etc) , And we were already hosting it on our own server for normal hls streaming purposes so we had a lot of experience with it and we knew how to integrate it with our existing infrastructure , it also had a very good documentation and a very active community which made it very easy for us to understand how to use it and how to integrate it with our existing infrastructure . &lt;/p&gt;

&lt;p&gt;There was also another solution I never evaluated: LiveKit. Had I looked at it earlier I might have gone with it instead, although given the time constraints I still think familiarity and existing infrastructure would probably have outweighed technical elegance.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we ended up choosing
&lt;/h2&gt;

&lt;p&gt;At this point you can probably guess what we chose.&lt;/p&gt;

&lt;p&gt;We ended up going with SRS for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We were already hosting it.&lt;/li&gt;
&lt;li&gt;We already knew how to operate it.&lt;/li&gt;
&lt;li&gt;Integration with our existing infrastructure was straightforward.&lt;/li&gt;
&lt;li&gt;Documentation was excellent.&lt;/li&gt;
&lt;li&gt;The community was active.&lt;/li&gt;
&lt;li&gt;It fit the timeline better than every other option.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;If I want the reader to take away just one thing from this story, it's pragmatism.&lt;/p&gt;

&lt;p&gt;Most of the time, you won't have the luxury of unlimited time or constraint-free requirements. Engineering isn't always about choosing the technically best solution—it's about choosing the solution that best fits your constraints, your team, and your timeline.&lt;/p&gt;

&lt;p&gt;That's exactly what happened here. SRS wasn't necessarily the "best" solution on paper, but it was the one that fit our constraints, integrated well with our existing infrastructure, and allowed us to deliver the feature on time. In the end, that's what mattered.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>javascript</category>
      <category>streaming</category>
      <category>webdev</category>
    </item>
    <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="799" 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="799" 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="271"&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="799" 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="286"&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="286"&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>
