<?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: Saurav Dhakal</title>
    <description>The latest articles on DEV Community by Saurav Dhakal (@sauravdhakal12).</description>
    <link>https://dev.to/sauravdhakal12</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1933139%2F63be4cbf-f84c-4c17-9d53-76cd4d8f6d78.png</url>
      <title>DEV Community: Saurav Dhakal</title>
      <link>https://dev.to/sauravdhakal12</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sauravdhakal12"/>
    <language>en</language>
    <item>
      <title>The Likes Table Problem: Why We Went Polymorphic.</title>
      <dc:creator>Saurav Dhakal</dc:creator>
      <pubDate>Sat, 21 Feb 2026 16:26:32 +0000</pubDate>
      <link>https://dev.to/sauravdhakal12/the-likes-table-problem-why-we-went-polymorphic-5dk1</link>
      <guid>https://dev.to/sauravdhakal12/the-likes-table-problem-why-we-went-polymorphic-5dk1</guid>
      <description>&lt;p&gt;A few days ago, I was working on adding a &lt;strong&gt;Community&lt;/strong&gt; section to an application. The idea was simple, users should be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create posts&lt;/li&gt;
&lt;li&gt;Leave comments&lt;/li&gt;
&lt;li&gt;Like posts&lt;/li&gt;
&lt;li&gt;Like comments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also had a separate News section. The new requirement was users should be able to like news articles as well.&lt;/p&gt;

&lt;p&gt;Building model for &lt;code&gt;posts&lt;/code&gt; and &lt;code&gt;comments&lt;/code&gt; was pretty straight forward. The real challenge was to model the&lt;code&gt;likes&lt;/code&gt;table.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: How Do We Store Likes?
&lt;/h2&gt;

&lt;p&gt;We’re using PostgreSQL, so enforcing relationships with foreign keys is easy and clean.&lt;/p&gt;

&lt;p&gt;If only &lt;strong&gt;one&lt;/strong&gt; thing could be liked (say, News), the schema would be simple, we would have a &lt;code&gt;news_like&lt;/code&gt; table which could look something like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;user_id&lt;/th&gt;
&lt;th&gt;news_id&lt;/th&gt;
&lt;th&gt;timestamp&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;(foreign key)&lt;/td&gt;
&lt;td&gt;(foreign key)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;But we didn’t have one entity. We had three. &lt;code&gt;posts&lt;/code&gt;, &lt;code&gt;comments&lt;/code&gt; and &lt;code&gt;news&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We had to decide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do we create three separate like tables? Or do we design one flexible solution?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Option 1: Three Separate Tables
&lt;/h2&gt;

&lt;p&gt;We could create three tables: &lt;code&gt;post_likes&lt;/code&gt; , &lt;code&gt;comment_likes&lt;/code&gt; and &lt;code&gt;news_likes&lt;/code&gt; . Each table would have proper foreign key relationships. This approach  would be a clean relational way of doing things. It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keeps strong relational integrity&lt;/li&gt;
&lt;li&gt;Makes joins easy&lt;/li&gt;
&lt;li&gt;Keeps structure explicit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the most “pure relational” approach. But it felt repetitive. The schema grows horizontally. &lt;/p&gt;

&lt;p&gt;And if tomorrow we add something else that can be liked, we’d need yet another table.&lt;/p&gt;

&lt;p&gt;It works, but it doesn’t scale elegantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: A Polymorphic Table (What We Chose)
&lt;/h2&gt;

&lt;p&gt;Instead of multiple tables, we created a &lt;strong&gt;single polymorphic likes table&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Polymorphic Table?
&lt;/h3&gt;

&lt;p&gt;A polymorphic table can reference multiple types of resources using a shared structure.&lt;/p&gt;

&lt;p&gt;We designed our &lt;code&gt;likes&lt;/code&gt; table to look something like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;user_id&lt;/th&gt;
&lt;th&gt;resource_id&lt;/th&gt;
&lt;th&gt;resource_type&lt;/th&gt;
&lt;th&gt;timestamp&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;(foreign key)&lt;/td&gt;
&lt;td&gt;(uuid)&lt;/td&gt;
&lt;td&gt;(POST / COMMENT / NEWS)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here’s how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user_id&lt;/code&gt;: who liked, foreign key to &lt;code&gt;users&lt;/code&gt; table.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resource_id&lt;/code&gt; : the UUID of the item, just the uuid, no foreign key relation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resource_type&lt;/code&gt; : what type of item it is&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;timestamp&lt;/code&gt; : timestamp&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of a strict foreign key to one table, we store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ID&lt;/li&gt;
&lt;li&gt;The type of resource&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, they uniquely identify what was liked.&lt;/p&gt;

&lt;p&gt;With this approach, we had one clean and centralized table to store all kinds of likes. It’s much easier to expand  and flexible. Since “like” is a feature common to many parts of the system, this design keeps it generic and reusable.&lt;/p&gt;

&lt;p&gt;But it does has a major downside. We lose direct foreign key enforcement on &lt;code&gt;resource_id&lt;/code&gt;. Because PostgreSQL can’t enforce a foreign key that dynamically points to multiple tables, referential integrity must be handled at the application level. We cannot write a simple join query to join from &lt;code&gt;comments&lt;/code&gt; table or &lt;code&gt;posts&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;For example, to fetch likes for a resource:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;SELECT&lt;/span&gt; &lt;span class="nc"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;FROM&lt;/span&gt; &lt;span class="nx"&gt;likes&lt;/span&gt;
&lt;span class="nx"&gt;WHERE&lt;/span&gt; &lt;span class="nx"&gt;resource_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-uuid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;AND&lt;/span&gt; &lt;span class="nx"&gt;resource_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if we need resource details plus likes, we may need separate queries or application-side logic.&lt;/p&gt;

&lt;p&gt;For our use case though, that trade-off was acceptable. We don’t perform heavy cross-entity joins on likes, so the downside was minimal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Design Felt Right
&lt;/h2&gt;

&lt;p&gt;The key insight was this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Like” is not tightly coupled to Posts, Comments, or News. It’s a behavior shared across resources.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By modeling it polymorphically, we treated “like” as a reusable system capability rather than a feature embedded in each entity.&lt;/p&gt;

&lt;p&gt;And as our application grows, this decision will likely save us refactoring time.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>database</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Why I Ended Up Adding Sessions to a JWT-Based System</title>
      <dc:creator>Saurav Dhakal</dc:creator>
      <pubDate>Thu, 19 Feb 2026 16:33:19 +0000</pubDate>
      <link>https://dev.to/sauravdhakal12/why-i-ended-up-adding-sessions-to-a-jwt-based-system-4m2i</link>
      <guid>https://dev.to/sauravdhakal12/why-i-ended-up-adding-sessions-to-a-jwt-based-system-4m2i</guid>
      <description>&lt;p&gt;Recently, I was working on an application where a new requirement came up: users should be able to see all the devices they are logged in from and log out from a specific device if needed.&lt;/p&gt;

&lt;p&gt;This was something I hadn’t implemented before, which made it an interesting challenge.&lt;/p&gt;

&lt;p&gt;At that point, the application was using JWT-based authentication. After a successful login, a JWT was generated and stored on client's side, and every request sent this token back to the server for authentication.&lt;/p&gt;

&lt;p&gt;This approach worked well and had a major advantage: the server didn’t need to store any authentication state. That made the system simple, scalable, and easy to reason about.&lt;/p&gt;

&lt;p&gt;But it also came with a limitation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Limitation of Stateless JWTs
&lt;/h2&gt;

&lt;p&gt;JWTs are stateless by design. Once a token is issued, the server has no native way to know how many devices a user is logged in from, which device a request is coming from, or whether access from a specific device should be revoked.&lt;/p&gt;

&lt;p&gt;As soon as features like device management or remote logout are needed, this lack of state becomes a real problem.&lt;/p&gt;

&lt;p&gt;At that point, it became clear that the backend needed &lt;em&gt;some&lt;/em&gt; form of state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Session Storage
&lt;/h2&gt;

&lt;p&gt;The solution I ended up with was introducing a &lt;code&gt;sessions&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;Each successful login creates a session record representing a single device or login instance. Along with the user reference, the session stores lightweight metadata such as device information, approximate location, login time, and last activity. This gives the system visibility into active logins without becoming overly complex.&lt;/p&gt;

&lt;p&gt;At this point, the system becomes &lt;em&gt;session-aware&lt;/em&gt;, but JWTs are still kept in place.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWTs with a Session Reference
&lt;/h2&gt;

&lt;p&gt;Instead of replacing JWTs, a small change was made: the generated JWT now includes a &lt;code&gt;sessionId&lt;/code&gt; in its payload. The token is still signed, still validated as usual, but now it also carries a reference to server-side state.&lt;/p&gt;

&lt;p&gt;On each authenticated request, the server validates the JWT and then checks whether the referenced session still exists. If it does, the request is allowed. If it doesn’t, the request is rejected.&lt;/p&gt;

&lt;p&gt;This single check enables remote logout.&lt;/p&gt;

&lt;p&gt;When a user logs out from a specific device, the corresponding session record is deleted. Any future request from that device will fail authentication, even if the JWT itself hasn’t expired yet.&lt;/p&gt;

&lt;p&gt;This also made it possible to list the devices a user is logged in from. Since the sessions table stores the userId, a single user logging in from multiple devices simply results in multiple session entries. Logging out from a specific device is then just a matter of deleting the corresponding session record. The next time that device makes a request, authentication fails.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Understanding Providers and Dependency Injection in NestJS</title>
      <dc:creator>Saurav Dhakal</dc:creator>
      <pubDate>Tue, 10 Feb 2026 17:03:40 +0000</pubDate>
      <link>https://dev.to/sauravdhakal12/understanding-providers-and-dependency-injection-in-nestjs-531b</link>
      <guid>https://dev.to/sauravdhakal12/understanding-providers-and-dependency-injection-in-nestjs-531b</guid>
      <description>&lt;p&gt;When I first started working with NestJS, registering providers (and controllers) inside a module felt like nothing more than a chore.&lt;/p&gt;

&lt;p&gt;It was one of those things I did because &lt;em&gt;“that’s just how Nest is designed.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Even after I learned that modules exist to build an application graph, which it uses internally to resolve relationships and dependencies between modules and providers, the idea still felt vague and abstract. I understood what was happening, but not really why it worked the way it did.&lt;/p&gt;

&lt;p&gt;Recently, I decided to take a deeper dive into how providers are registered and how Nest actually injects them. It turned out to be far more interesting than I expected.&lt;/p&gt;

&lt;p&gt;Here’s what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, let’s understand what Dependency Injection is.
&lt;/h2&gt;

&lt;p&gt;Wikipedia defines Dependency Injection(DI) as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Dependency Injection&lt;/strong&gt; is a programming technique in which an object or &lt;a href="https://en.wikipedia.org/wiki/Subroutine" rel="noopener noreferrer"&gt;f&lt;/a&gt;unction receives other objects or functions that it requires, as opposed to creating them internally.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s look at a simple example.&lt;/p&gt;

&lt;p&gt;Imagine a restaurant application. When a user’s order is ready for pickup, a notification needs to be sent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// code operating over orders&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notificationService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NotificationService&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;notificationService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&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, &lt;code&gt;OrderService&lt;/code&gt;handles order-related logic, and &lt;code&gt;NotificationService&lt;/code&gt;handles notifications.&lt;/p&gt;

&lt;p&gt;However, because &lt;code&gt;NotificationService&lt;/code&gt;is instantiated directly inside &lt;code&gt;OrderService&lt;/code&gt;using &lt;code&gt;new&lt;/code&gt;, this &lt;strong&gt;is not&lt;/strong&gt; dependency injection.&lt;/p&gt;

&lt;p&gt;Now compare that with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&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;notificationService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NotificationService&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="c1"&gt;// code operating over orders&lt;/span&gt;
  &lt;span class="nx"&gt;notificationService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is dependency injection.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OrderService&lt;/code&gt; no longer cares about how &lt;code&gt;NotificationService&lt;/code&gt; is created. It simply declares that it needs one, and something else provides it. That instance can also be reused or cached if the configuration is the same in multiple places.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Dependency Injection?
&lt;/h2&gt;

&lt;p&gt;Dependency Injection helps by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reducing coupling between classes&lt;/li&gt;
&lt;li&gt;Making testing easier (you can inject mock dependencies)&lt;/li&gt;
&lt;li&gt;Encouraging modular, maintainable code&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Dependency Injection Works in NestJS
&lt;/h2&gt;

&lt;p&gt;Alright, enough theory, this is where things start to get interesting.&lt;/p&gt;

&lt;p&gt;In NestJS, the basic flow looks something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define a provider using &lt;code&gt;@Injectable()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Register that provider with Nest&lt;/li&gt;
&lt;li&gt;Ask Nest to inject it using constructor-based injection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Registration usually happens in a module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&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;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;DemoService&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;DemoController&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;DemoModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, Nest becomes responsible for creating and managing instances of &lt;code&gt;DemoService&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nest’s IoC Container (The Missing Piece)
&lt;/h2&gt;

&lt;p&gt;NestJS uses an &lt;strong&gt;IoC (Inversion of Control) container&lt;/strong&gt; to manage dependencies.&lt;/p&gt;

&lt;p&gt;You can think of this container as a &lt;strong&gt;key-value&lt;/strong&gt; &lt;strong&gt;registry&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keys&lt;/strong&gt; are called &lt;em&gt;tokens&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Values&lt;/strong&gt; describe how to create or retrieve a dependency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&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;DemoService&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nest internally expands it into a  standard provider definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;providers&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;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DemoService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;useClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DemoService&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;In this case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;token&lt;/strong&gt; is &lt;code&gt;DemoService&lt;/code&gt; (the class itself)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useClass&lt;/code&gt; tells Nest which class to instantiate when that token is requested.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when Nest encounters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&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;demoService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DemoService&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;ol&gt;
&lt;li&gt;Nest looks up the &lt;code&gt;DemoService&lt;/code&gt; token in the IoC container&lt;/li&gt;
&lt;li&gt;It finds the matching provider record&lt;/li&gt;
&lt;li&gt;It resolves the provider (&lt;code&gt;useClass&lt;/code&gt; in this case)&lt;/li&gt;
&lt;li&gt;The instance is created (or reused, since providers are singletons by default)&lt;/li&gt;
&lt;li&gt;The resolved instance is injected into the class&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A Quick Note on &lt;code&gt;useValue&lt;/code&gt; and &lt;code&gt;useFactory&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useClass&lt;/code&gt; is the most common way to define a provider, but it’s not the only one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;useValue&lt;/code&gt;&lt;/strong&gt; lets you inject a constant or pre-created object&lt;/p&gt;

&lt;p&gt;Useful for configuration values, feature flags, or mocks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;useFactory&lt;/code&gt;&lt;/strong&gt; allows you to create a value dynamically&lt;/p&gt;

&lt;p&gt;Nest runs a function and injects whatever it returns.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three (&lt;code&gt;useClass&lt;/code&gt;, &lt;code&gt;useValue&lt;/code&gt;, and &lt;code&gt;useFactory&lt;/code&gt;) exist for the same reason:&lt;/p&gt;

&lt;p&gt;they tell the IoC container how to resolve a token when it’s requested.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>node</category>
      <category>tutorial</category>
      <category>typescript</category>
    </item>
    <item>
      <title>NestJS - Maintaining transactional integrity across services</title>
      <dc:creator>Saurav Dhakal</dc:creator>
      <pubDate>Sun, 08 Feb 2026 08:45:51 +0000</pubDate>
      <link>https://dev.to/sauravdhakal12/nestjs-maintaining-transactional-integrity-across-services-559b</link>
      <guid>https://dev.to/sauravdhakal12/nestjs-maintaining-transactional-integrity-across-services-559b</guid>
      <description>&lt;p&gt;I’ve been using NestJS for quite a while now, both professionally and for pet projects. The way it enforces certain design principles makes it easy to get started and, more importantly, helps keep projects maintainable in the long run. Compared to plain Express, which I used a few years back, Nest brings a lot of structure that naturally scales with application complexity.&lt;/p&gt;

&lt;p&gt;That said, there was one thing I kept struggling with: &lt;strong&gt;maintaining transactional integrity across services&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In NestJS, we typically break applications into modules based on features or domains. Each module contains services, and those services encapsulate business logic. A single module may have multiple services, each exposing several methods that handle specific business actions. These services often call one another, sometimes even across module boundaries.&lt;/p&gt;

&lt;p&gt;The problem starts when a service needs to orchestrate multiple other services, each of which performs changes in the database. In such cases, we often want all those changes to be &lt;strong&gt;atomic:&lt;/strong&gt; either everything succeeds, or everything is rolled back.&lt;/p&gt;

&lt;p&gt;Consider an order management system as an example. An &lt;code&gt;OrderService&lt;/code&gt; might:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;call an &lt;code&gt;InventoryService&lt;/code&gt; to reduce stock,&lt;/li&gt;
&lt;li&gt;call a &lt;code&gt;LedgerService&lt;/code&gt; to record financial changes,&lt;/li&gt;
&lt;li&gt;and possibly trigger other side effects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these operations must succeed together. If any one of them fails, the system should revert all previously applied changes. This is where database transactions, commit and rollback, come into play.&lt;/p&gt;

&lt;p&gt;Most ORMs make this relatively straightforward. For example, in Prisma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$transaction&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tx&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="c1"&gt;// operations using tx&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this level, transactions are easy to work with. The real challenge, however, is &lt;strong&gt;how to pass this transaction context cleanly across multiple services&lt;/strong&gt; without polluting method signatures or tightly coupling services together.&lt;/p&gt;

&lt;p&gt;And that’s where things start to get tricky.&lt;/p&gt;

&lt;p&gt;How do we pass this transaction around? One obvious and simple solution would be to make each service accept and optional argument, the transaction itself. Something like&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;async&lt;/span&gt; &lt;span class="nf"&gt;someService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;argA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;argB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...,&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt;&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="c1"&gt;//code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, but as the application grows, it quickly becomes messy.&lt;/p&gt;

&lt;p&gt;The transaction parameter starts appearing everywhere, even in methods that don’t always need it. Debugging becomes harder, method signatures become noisy, and transaction objects get passed deeper and deeper through the call stack.&lt;/p&gt;

&lt;p&gt;After running into this a few times, I started wondering: isn’t there a cleaner way to do this?&lt;/p&gt;

&lt;p&gt;As it turns out, there is. Before getting to that, though, we need to understand Node’s &lt;strong&gt;Async Local Storage&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the hell is an Async Local Storage?
&lt;/h2&gt;

&lt;p&gt;Node.js provides a feature called &lt;strong&gt;Async Local Storage&lt;/strong&gt; (ALS), built on top of the &lt;code&gt;async_hooks&lt;/code&gt; API.The official documentation describes it like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AsyncLocalStorage allows storing data throughout the lifetime of a web request or any other asynchronous duration. It is similar to thread-local storage in other languages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In simpler terms, &lt;strong&gt;Async Local Storage lets you attach data to an asynchronous execution context and access it anywhere down the async call chain,&lt;/strong&gt; without explicitly passing it around as a function argument.&lt;/p&gt;

&lt;p&gt;If you come from languages like Java or C#, you can think of it as the Node.js equivalent of &lt;strong&gt;thread-local storage&lt;/strong&gt;. Since JavaScript doesn’t have threads in the same way, ALS instead tracks &lt;strong&gt;async execution contexts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can think of it like a hidden backpack. You put something into the backpack at the start of a request, like a database transaction, and any code executed as part of that request can retrieve it later, without knowing who put it there or how it got passed down.&lt;/p&gt;

&lt;p&gt;We can initialize ALS once (for example, in middleware) and then use it throughout the entire request lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  A minimal ALS Setup
&lt;/h2&gt;

&lt;p&gt;First, we create a shared Async Local Storage instance:&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="c1"&gt;// als.ts&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;AsyncLocalStorage&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;node:async_hooks&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;const&lt;/span&gt; &lt;span class="nx"&gt;als&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is like defining the “backpack” where we’ll store transaction and other stuff and use per request.&lt;/p&gt;

&lt;p&gt;Next, we initialize a new async context in middleware:&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="c1"&gt;// als.middleware.ts&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;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&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;express&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;als&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;./als&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;function&lt;/span&gt; &lt;span class="nf"&gt;alsMiddleware&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;Request&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="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;any&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;als&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;,&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="nf"&gt;next&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, &lt;code&gt;als.run(store, () =&amp;gt; next())&lt;/code&gt; creates a new async context and ensures that &lt;strong&gt;everything that happens after &lt;code&gt;next()&lt;/code&gt; shares the same &lt;code&gt;store&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, we register the middleware:&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="c1"&gt;// app.module.ts&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;MiddlewareConsumer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NestModule&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;alsMiddleware&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;./als.middleware&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="kr"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;NestModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MiddlewareConsumer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alsMiddleware&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forRoutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, every request gets its own isolated context, which can be accessed anywhere during that request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading and writing from the context
&lt;/h2&gt;

&lt;p&gt;To store something in the ALS context:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;als&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;./als&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;SomeService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;doSomething&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;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;als&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStore&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="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&lt;/span&gt;&lt;span class="dl"&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;bar&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;And to access:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;als&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStore&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;foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No extra parameters. No tight coupling. Just request-scoped state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using ALS with transactions
&lt;/h2&gt;

&lt;p&gt;Now we can come back to the original problem.&lt;/p&gt;

&lt;p&gt;Here’s a simple example using Prisma:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;als&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;./als&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;SomeService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;als&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStore&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="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tx&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="nf"&gt;serviceA&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;serviceB&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&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;Inside the transaction callback, we store the Prisma transaction object in ALS. From this point on, any service called as part of this request can retrieve the transaction from ALS and use it, without having it explicitly passed in.&lt;/p&gt;

&lt;p&gt;This keeps service APIs clean, avoids deeply nested transaction plumbing, and lets transactions remain a cross-cutting concern rather than a business-logic detail.&lt;/p&gt;

&lt;p&gt;Learning this approach has been a nice win for me, and I’ve been happily using it ever since. It removed a lot of friction around transactions in NestJS. How are you solving this in your own applications?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>nestjs</category>
      <category>database</category>
    </item>
    <item>
      <title>Understanding JavaScript's Asynchronous Magic: Event Loop, Web APIs, and the Call Stack</title>
      <dc:creator>Saurav Dhakal</dc:creator>
      <pubDate>Thu, 01 May 2025 14:50:45 +0000</pubDate>
      <link>https://dev.to/sauravdhakal12/understanding-javascripts-asynchronous-magic-event-loop-web-apis-and-the-call-stack-4lb2</link>
      <guid>https://dev.to/sauravdhakal12/understanding-javascripts-asynchronous-magic-event-loop-web-apis-and-the-call-stack-4lb2</guid>
      <description>&lt;p&gt;When I first started working with JavaScript, I used async functions like 'fetch()' or 'setTimeout()' every day — but I never really understood how they worked behind the scenes.&lt;/p&gt;

&lt;p&gt;It was just "magic": you call something, and sometime later, it gives you back a result.&lt;/p&gt;

&lt;p&gt;Recently, I decided to dive deeper into how JavaScript handles asynchronous operations — and it completely changed the way I&lt;br&gt;
see JavaScript.&lt;/p&gt;

&lt;p&gt;In this post, I’ll explain (in simple terms) how the call stack, Web APIs, callback queues, and the event loop work together &lt;br&gt;
to make async code possible.&lt;/p&gt;
&lt;h2&gt;
  
  
  JavaScript is Single Threaded
&lt;/h2&gt;

&lt;p&gt;JavaScript is a single-threaded language.This means, JS uses a single call stack. So, only one piece of code can run at a time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="mi"&gt;1&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="mi"&gt;2&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this simple program, single line is executed at a time. Each 'console.log()' is added to call stack, executed and poped off once completed. So code, executes synchronously, line by line, top to bottom.&lt;/p&gt;

&lt;p&gt;That’s fine for most things — until we hit something that takes time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with blocking code
&lt;/h2&gt;

&lt;p&gt;Imagine calling a function that takes 5 second to execute. Since JS runs synchronously, it'll just.. wait. Nothing else runs until that function finishes. This blocks the stack — and with it, your entire app.&lt;/p&gt;

&lt;p&gt;This is not ideal. Imagine a network request blocks the stack and makes our entire application unresponsive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Asynchronous Programming
&lt;/h2&gt;

&lt;p&gt;To avoid blocking, JavaScript (along with the environment it runs in — like browsers or Node.js) uses a set of tools: Web APIs, callback/task queues, and the event loop.&lt;/p&gt;

&lt;p&gt;This trio helps JS handle things like network requests, timers, or file operations without freezing the app.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Web APIs:&lt;br&gt;
Web APIs are a set of features provided by the environment (like the browser or Node.js) to handle operations that might otherwise block the main call stack.&lt;br&gt;
For example, the fetch function — used to retrieve data from the internet — is a Web API provided by the browser.&lt;br&gt;
When you call fetch, it runs outside of the main call stack, so it doesn't block the rest of your code from running.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Callback/task queue&lt;br&gt;
When you use Web APIs, you often provide a callback function — a piece of code that should run after the operation finishes.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example-api.com/data&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="nf"&gt;then&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="c1"&gt;// Do something with data returned&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Rest of code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;In the above example, we make a fetch request. The .then method is used to register a callback function. When the response is available, the function you provided inside .then is queued — it waits in the callback queue.&lt;br&gt;
The callback queue holds all such functions waiting to be executed.&lt;br&gt;
But they don't immediately run — this is where the event loop comes in.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Event Loop&lt;br&gt;
The event loop is a loop that constantly checks two things:&lt;br&gt;
    - Is the call stack empty?&lt;br&gt;
    - Are there any functions in the callback queue?&lt;/p&gt;

&lt;p&gt;If the call stack is empty and there’s a function waiting in the callback queue, the event loop pushes that function onto the call stack, allowing it to run.&lt;br&gt;
This is how JavaScript handles asynchronous behavior without blocking the main thread.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it all works (High level)
&lt;/h2&gt;

&lt;p&gt;When you run a function like fetch(), the browser (not JavaScript itself) handles it using its Web APIs. Once the operation completes, it doesn’t just jump back into the call stack. Instead, a callback function (or a resolve function in case of a promise) is queued.&lt;br&gt;
That callback sits in a task queue or microtask queue. After the main code is done (i.e., the call stack is empty), the event loop starts checking the queues.&lt;br&gt;
If it finds any callbacks, it pushes them onto the call stack — where they get executed like any other function.&lt;br&gt;
This makes async feel synchronous in some cases, without actually blocking the code.&lt;/p&gt;

&lt;p&gt;This system confused me for a long time. I used async code every day, but I never asked what actually happens. Once I saw the call stack, Web APIs, queue, and event loop as a team, it all made sense.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The JavaScript Course That Made Me Curious Again</title>
      <dc:creator>Saurav Dhakal</dc:creator>
      <pubDate>Sun, 13 Apr 2025 07:48:22 +0000</pubDate>
      <link>https://dev.to/sauravdhakal12/the-javascript-course-that-made-me-curious-again-5158</link>
      <guid>https://dev.to/sauravdhakal12/the-javascript-course-that-made-me-curious-again-5158</guid>
      <description>&lt;p&gt;I recently took a course on Frontend Masters — &lt;strong&gt;JavaScript: The Hard Parts, v2.&lt;/strong&gt; This course made me realize how little I truly understood JavaScript.&lt;/p&gt;

&lt;p&gt;I’ve been building web apps with JavaScript “professionally” as a backend engineer for a while now. I’ve gotten to a point where setting up new projects or making changes to existing ones feels almost effortless — the kind of stuff that used to scare me early on.&lt;/p&gt;

&lt;p&gt;But maybe that’s exactly the problem. I stopped getting curious.&lt;/p&gt;

&lt;p&gt;Back when I was just starting out, when I knew so little, I was desperate to understand it all. How Node works under the hood. What promises really are. What’s the deal with “this”. I’d question anything I could. And I loved it.&lt;/p&gt;

&lt;p&gt;These days? I mostly do what I need to do — and move on. I don’t think much about what’s happening behind the scenes. Maybe it’s the “professional” mindset kicking in. Or maybe somewhere along the way, I started losing the sense of play that got me into this field in the first place.&lt;/p&gt;

&lt;p&gt;I came across this course through a blog post. I don’t remember what blog it was, but the course seemed interesting. I was on my semester break, had plenty of free time — so I decided to take it. And I’m so glad I did.&lt;/p&gt;

&lt;p&gt;Because taking this course made me realize how much I didn’t know — even though I use most of this stuff every day.&lt;/p&gt;

&lt;p&gt;And honestly, that’s okay. Not knowing isn’t the problem. What matters is the curiosity. The urge to dig deeper, to play around, to ask “why” even when things seem to work fine.&lt;/p&gt;

&lt;p&gt;That’s how I grew in the beginning. That’s what got me hooked.&lt;/p&gt;

&lt;p&gt;Somewhere along the way, I lost that.&lt;/p&gt;

&lt;p&gt;So, what I aim for in the days to come is to be more curious — to find time, now and then, to question what I know and how things actually work. To check if I really understand it, or if it’s just muscle memory getting me by.&lt;/p&gt;

&lt;p&gt;Because this — this urge to dig deeper — is what keeps the craft alive.&lt;/p&gt;

&lt;p&gt;It’s how we grow. It’s how we keep learning. And maybe most importantly, it’s what keeps the joy alive.&lt;/p&gt;

&lt;p&gt;And I don’t want to lose that again.&lt;/p&gt;

&lt;p&gt;(Originally published on &lt;a href="https://www.sauravdhakal.com.np" rel="noopener noreferrer"&gt;https://www.sauravdhakal.com.np&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>coding</category>
      <category>growth</category>
    </item>
  </channel>
</rss>
