<?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>Forem: Yogesh Prasad</title>
    <description>The latest articles on Forem by Yogesh Prasad (@devto_with_yog).</description>
    <link>https://forem.com/devto_with_yog</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%2F1993629%2F1a27012d-e041-4449-aeed-22b8431056c5.jpg</url>
      <title>Forem: Yogesh Prasad</title>
      <link>https://forem.com/devto_with_yog</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/devto_with_yog"/>
    <language>en</language>
    <item>
      <title>🧠 Mastering Goroutines in Go: The Power of Lightweight Concurrency.</title>
      <dc:creator>Yogesh Prasad</dc:creator>
      <pubDate>Mon, 03 Nov 2025 08:58:36 +0000</pubDate>
      <link>https://forem.com/devto_with_yog/mastering-goroutines-in-go-the-power-of-lightweight-concurrency-4bjo</link>
      <guid>https://forem.com/devto_with_yog/mastering-goroutines-in-go-the-power-of-lightweight-concurrency-4bjo</guid>
      <description>&lt;p&gt;Go (Golang) is known for its simplicity, performance, and concurrency model.&lt;br&gt;
At the heart of this concurrency lies one of Go’s most elegant features — the goroutine.&lt;/p&gt;

&lt;p&gt;In this blog, we’ll explore what goroutines are, how they work under the hood, and how you can use them to build concurrent, scalable applications like a seasoned Go developer.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧩 What is a Goroutine?
&lt;/h2&gt;

&lt;p&gt;A goroutine is a lightweight thread managed by the Go runtime.&lt;/p&gt;

&lt;p&gt;When you run:&lt;/p&gt;

&lt;p&gt;go doSomething()&lt;/p&gt;

&lt;p&gt;you’re telling Go:&lt;/p&gt;

&lt;p&gt;“Run doSomething() asynchronously, and don’t wait for it to finish.”&lt;/p&gt;

&lt;p&gt;That single keyword go launches a new goroutine.&lt;/p&gt;

&lt;p&gt;Unlike traditional OS threads (which can take up megabytes of stack memory), a goroutine starts with only a few kilobytes — making it possible to spawn hundreds of thousands of them effortlessly.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚙️ How Goroutines Work (Under the Hood)
&lt;/h2&gt;

&lt;p&gt;Go uses an efficient M:N scheduler, meaning it maps:&lt;/p&gt;

&lt;p&gt;M = OS threads&lt;/p&gt;

&lt;p&gt;N = Goroutines&lt;/p&gt;

&lt;p&gt;So, instead of each goroutine needing its own thread, the Go runtime multiplexes thousands of goroutines onto a few OS threads — automatically managing scheduling, context switching, and load balancing.&lt;/p&gt;

&lt;p&gt;This is why goroutines are incredibly lightweight and efficient.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 The Lifecycle of a Goroutine
&lt;/h2&gt;

&lt;p&gt;You launch it with go ...&lt;/p&gt;

&lt;p&gt;The Go scheduler places it in a run queue&lt;/p&gt;

&lt;p&gt;The scheduler assigns it to an available P (processor context)&lt;/p&gt;

&lt;p&gt;The goroutine executes&lt;/p&gt;

&lt;p&gt;When it finishes (or main() exits), it’s garbage collected&lt;/p&gt;

&lt;p&gt;Important: When the main function ends, all goroutines stop — no exceptions.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧪 Example 1: Your First Goroutine
&lt;/h2&gt;

&lt;p&gt;Let’s start simple:&lt;/p&gt;

&lt;p&gt;package main&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import (
    "fmt"
    "time"
)

func main() {
    go fmt.Println("Hello from a goroutine!")
    time.Sleep(time.Millisecond * 10)
}

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

&lt;/div&gt;



&lt;p&gt;Without the time.Sleep, this program might print nothing — because the main goroutine exits before the child one gets CPU time.&lt;/p&gt;

&lt;p&gt;✅ Lesson: The main goroutine must stay alive until others finish.&lt;/p&gt;

&lt;p&gt;🧱 Example 2: Launching Multiple Goroutines&lt;br&gt;
package main&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "fmt"

func main() {
    for i := 1; i &amp;lt;= 5; i++ {
        go fmt.Println("Goroutine:", i)
    }

    fmt.Scanln() // Wait for user input to prevent exit
}

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

&lt;/div&gt;



&lt;p&gt;You’ll notice the output order is unpredictable — and that’s expected!&lt;br&gt;
Each goroutine runs concurrently, not sequentially.&lt;/p&gt;

&lt;p&gt;🔗 Communication Between Goroutines — Channels&lt;/p&gt;

&lt;p&gt;Goroutines are great, but they’re even more powerful when they communicate safely.&lt;br&gt;
That’s where channels come in.&lt;/p&gt;

&lt;p&gt;A channel is a pipe that allows goroutines to send and receive data.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "fmt"

func main() {
    ch := make(chan string)

    go func() {
        ch &amp;lt;- "Hello from goroutine!"
    }()

    msg := &amp;lt;-ch
    fmt.Println(msg)
}

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

&lt;/div&gt;



&lt;p&gt;ch &amp;lt;- "Hello" sends data&lt;/p&gt;

&lt;p&gt;&amp;lt;-ch receives data&lt;/p&gt;

&lt;p&gt;Both send and receive block until the other side is ready — ensuring synchronization.&lt;/p&gt;

&lt;p&gt;⚙️ Buffered Channels&lt;/p&gt;

&lt;p&gt;Want to send without waiting immediately? Use a buffered channel:&lt;/p&gt;

&lt;p&gt;ch := make(chan int, 2)&lt;br&gt;
ch &amp;lt;- 1&lt;br&gt;
ch &amp;lt;- 2&lt;br&gt;
fmt.Println(&amp;lt;-ch)&lt;/p&gt;

&lt;p&gt;Here, the buffer lets you send two items before blocking.&lt;/p&gt;

&lt;p&gt;🧰 Controlling Goroutines with sync.WaitGroup&lt;/p&gt;

&lt;p&gt;In real-world apps, you’ll often need to wait for multiple goroutines to finish.&lt;br&gt;
That’s where sync.WaitGroup comes in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup

    for i := 1; i &amp;lt;= 3; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            fmt.Println("Worker", id, "done")
        }(i)
    }

    wg.Wait() // Wait until all goroutines finish
}

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

&lt;/div&gt;



&lt;p&gt;✅ This is the idiomatic Go way to synchronize goroutines.&lt;/p&gt;

&lt;p&gt;🏗 Real-World Example: Worker Pool Pattern&lt;/p&gt;

&lt;p&gt;A worker pool limits the number of concurrent workers — an essential pattern in production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "time"
)

func worker(id int, jobs &amp;lt;-chan int, results chan&amp;lt;- int) {
    for j := range jobs {
        fmt.Println("Worker", id, "started job", j)
        time.Sleep(time.Second)
        fmt.Println("Worker", id, "finished job", j)
        results &amp;lt;- j * 2
    }
}

func main() {
    jobs := make(chan int, 5)
    results := make(chan int, 5)

    for w := 1; w &amp;lt;= 3; w++ {
        go worker(w, jobs, results)
    }

    for j := 1; j &amp;lt;= 5; j++ {
        jobs &amp;lt;- j
    }
    close(jobs)

    for a := 1; a &amp;lt;= 5; a++ {
        &amp;lt;-results
    }
}

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

&lt;/div&gt;



&lt;p&gt;💡 Conceptually:&lt;/p&gt;

&lt;p&gt;Jobs channel → queue of tasks&lt;/p&gt;

&lt;p&gt;Results channel → output&lt;/p&gt;

&lt;p&gt;Workers (goroutines) → process jobs concurrently&lt;/p&gt;

&lt;p&gt;⚠️ Common Pitfalls&lt;/p&gt;

&lt;p&gt;❌ Forgetting to close channels — can cause deadlocks&lt;/p&gt;

&lt;p&gt;❌ Starting goroutines without control — can overwhelm system memory&lt;/p&gt;

&lt;p&gt;❌ Accessing shared memory without sync — causes race conditions&lt;/p&gt;

&lt;p&gt;You can detect races by running:&lt;/p&gt;

&lt;p&gt;go run -race main.go&lt;/p&gt;

&lt;h2&gt;
  
  
  🧭 Key Takeaways
&lt;/h2&gt;

&lt;p&gt;✅ Goroutines are lightweight, cheap, and managed by Go’s scheduler&lt;br&gt;
✅ Channels enable safe communication between them&lt;br&gt;
✅ Always synchronize goroutines using WaitGroups, channels, or contexts&lt;br&gt;
✅ Never start a goroutine you can’t stop&lt;/p&gt;

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

&lt;p&gt;Goroutines are the foundation of Go’s simplicity and power.&lt;br&gt;
Once you master them, you’ll start thinking in concurrent patterns — building systems that scale effortlessly.&lt;/p&gt;

&lt;p&gt;In upcoming posts, I’ll dive deeper into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context cancellation&lt;/li&gt;
&lt;li&gt;Pipelines&lt;/li&gt;
&lt;li&gt;Fan-out/Fan-in patterns&lt;/li&gt;
&lt;li&gt;Real-world concurrency debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✍️ Written by &lt;a href="https://dev.to/devto_with_yog"&gt;Yogesh Mathankar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 Modern MERN &amp;amp; Go developer passionate about building scalable systems and AI-integrated apps.&lt;/p&gt;

</description>
      <category>go</category>
      <category>backenddevelopment</category>
      <category>goroutine</category>
    </item>
    <item>
      <title>🧠 Mastering Goroutines in Go: The Power of Lightweight Concurrency.</title>
      <dc:creator>Yogesh Prasad</dc:creator>
      <pubDate>Mon, 03 Nov 2025 08:58:36 +0000</pubDate>
      <link>https://forem.com/devto_with_yog/mastering-goroutines-in-go-the-power-of-lightweight-concurrency-3iik</link>
      <guid>https://forem.com/devto_with_yog/mastering-goroutines-in-go-the-power-of-lightweight-concurrency-3iik</guid>
      <description>&lt;p&gt;Go (Golang) is known for its simplicity, performance, and concurrency model.&lt;br&gt;
At the heart of this concurrency lies one of Go’s most elegant features — the goroutine.&lt;/p&gt;

&lt;p&gt;In this blog, we’ll explore what goroutines are, how they work under the hood, and how you can use them to build concurrent, scalable applications like a seasoned Go developer.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧩 What is a Goroutine?
&lt;/h2&gt;

&lt;p&gt;A goroutine is a lightweight thread managed by the Go runtime.&lt;/p&gt;

&lt;p&gt;When you run:&lt;/p&gt;

&lt;p&gt;go doSomething()&lt;/p&gt;

&lt;p&gt;you’re telling Go:&lt;/p&gt;

&lt;p&gt;“Run doSomething() asynchronously, and don’t wait for it to finish.”&lt;/p&gt;

&lt;p&gt;That single keyword go launches a new goroutine.&lt;/p&gt;

&lt;p&gt;Unlike traditional OS threads (which can take up megabytes of stack memory), a goroutine starts with only a few kilobytes — making it possible to spawn hundreds of thousands of them effortlessly.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚙️ How Goroutines Work (Under the Hood)
&lt;/h2&gt;

&lt;p&gt;Go uses an efficient M:N scheduler, meaning it maps:&lt;/p&gt;

&lt;p&gt;M = OS threads&lt;/p&gt;

&lt;p&gt;N = Goroutines&lt;/p&gt;

&lt;p&gt;So, instead of each goroutine needing its own thread, the Go runtime multiplexes thousands of goroutines onto a few OS threads — automatically managing scheduling, context switching, and load balancing.&lt;/p&gt;

&lt;p&gt;This is why goroutines are incredibly lightweight and efficient.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 The Lifecycle of a Goroutine
&lt;/h2&gt;

&lt;p&gt;You launch it with go ...&lt;/p&gt;

&lt;p&gt;The Go scheduler places it in a run queue&lt;/p&gt;

&lt;p&gt;The scheduler assigns it to an available P (processor context)&lt;/p&gt;

&lt;p&gt;The goroutine executes&lt;/p&gt;

&lt;p&gt;When it finishes (or main() exits), it’s garbage collected&lt;/p&gt;

&lt;p&gt;Important: When the main function ends, all goroutines stop — no exceptions.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧪 Example 1: Your First Goroutine
&lt;/h2&gt;

&lt;p&gt;Let’s start simple:&lt;/p&gt;

&lt;p&gt;package main&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import (
    "fmt"
    "time"
)

func main() {
    go fmt.Println("Hello from a goroutine!")
    time.Sleep(time.Millisecond * 10)
}

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

&lt;/div&gt;



&lt;p&gt;Without the time.Sleep, this program might print nothing — because the main goroutine exits before the child one gets CPU time.&lt;/p&gt;

&lt;p&gt;✅ Lesson: The main goroutine must stay alive until others finish.&lt;/p&gt;

&lt;p&gt;🧱 Example 2: Launching Multiple Goroutines&lt;br&gt;
package main&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "fmt"

func main() {
    for i := 1; i &amp;lt;= 5; i++ {
        go fmt.Println("Goroutine:", i)
    }

    fmt.Scanln() // Wait for user input to prevent exit
}

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

&lt;/div&gt;



&lt;p&gt;You’ll notice the output order is unpredictable — and that’s expected!&lt;br&gt;
Each goroutine runs concurrently, not sequentially.&lt;/p&gt;

&lt;p&gt;🔗 Communication Between Goroutines — Channels&lt;/p&gt;

&lt;p&gt;Goroutines are great, but they’re even more powerful when they communicate safely.&lt;br&gt;
That’s where channels come in.&lt;/p&gt;

&lt;p&gt;A channel is a pipe that allows goroutines to send and receive data.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "fmt"

func main() {
    ch := make(chan string)

    go func() {
        ch &amp;lt;- "Hello from goroutine!"
    }()

    msg := &amp;lt;-ch
    fmt.Println(msg)
}

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

&lt;/div&gt;



&lt;p&gt;ch &amp;lt;- "Hello" sends data&lt;/p&gt;

&lt;p&gt;&amp;lt;-ch receives data&lt;/p&gt;

&lt;p&gt;Both send and receive block until the other side is ready — ensuring synchronization.&lt;/p&gt;

&lt;p&gt;⚙️ Buffered Channels&lt;/p&gt;

&lt;p&gt;Want to send without waiting immediately? Use a buffered channel:&lt;/p&gt;

&lt;p&gt;ch := make(chan int, 2)&lt;br&gt;
ch &amp;lt;- 1&lt;br&gt;
ch &amp;lt;- 2&lt;br&gt;
fmt.Println(&amp;lt;-ch)&lt;/p&gt;

&lt;p&gt;Here, the buffer lets you send two items before blocking.&lt;/p&gt;

&lt;p&gt;🧰 Controlling Goroutines with sync.WaitGroup&lt;/p&gt;

&lt;p&gt;In real-world apps, you’ll often need to wait for multiple goroutines to finish.&lt;br&gt;
That’s where sync.WaitGroup comes in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup

    for i := 1; i &amp;lt;= 3; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            fmt.Println("Worker", id, "done")
        }(i)
    }

    wg.Wait() // Wait until all goroutines finish
}

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

&lt;/div&gt;



&lt;p&gt;✅ This is the idiomatic Go way to synchronize goroutines.&lt;/p&gt;

&lt;p&gt;🏗 Real-World Example: Worker Pool Pattern&lt;/p&gt;

&lt;p&gt;A worker pool limits the number of concurrent workers — an essential pattern in production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "time"
)

func worker(id int, jobs &amp;lt;-chan int, results chan&amp;lt;- int) {
    for j := range jobs {
        fmt.Println("Worker", id, "started job", j)
        time.Sleep(time.Second)
        fmt.Println("Worker", id, "finished job", j)
        results &amp;lt;- j * 2
    }
}

func main() {
    jobs := make(chan int, 5)
    results := make(chan int, 5)

    for w := 1; w &amp;lt;= 3; w++ {
        go worker(w, jobs, results)
    }

    for j := 1; j &amp;lt;= 5; j++ {
        jobs &amp;lt;- j
    }
    close(jobs)

    for a := 1; a &amp;lt;= 5; a++ {
        &amp;lt;-results
    }
}

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

&lt;/div&gt;



&lt;p&gt;💡 Conceptually:&lt;/p&gt;

&lt;p&gt;Jobs channel → queue of tasks&lt;/p&gt;

&lt;p&gt;Results channel → output&lt;/p&gt;

&lt;p&gt;Workers (goroutines) → process jobs concurrently&lt;/p&gt;

&lt;p&gt;⚠️ Common Pitfalls&lt;/p&gt;

&lt;p&gt;❌ Forgetting to close channels — can cause deadlocks&lt;/p&gt;

&lt;p&gt;❌ Starting goroutines without control — can overwhelm system memory&lt;/p&gt;

&lt;p&gt;❌ Accessing shared memory without sync — causes race conditions&lt;/p&gt;

&lt;p&gt;You can detect races by running:&lt;/p&gt;

&lt;p&gt;go run -race main.go&lt;/p&gt;

&lt;h2&gt;
  
  
  🧭 Key Takeaways
&lt;/h2&gt;

&lt;p&gt;✅ Goroutines are lightweight, cheap, and managed by Go’s scheduler&lt;br&gt;
✅ Channels enable safe communication between them&lt;br&gt;
✅ Always synchronize goroutines using WaitGroups, channels, or contexts&lt;br&gt;
✅ Never start a goroutine you can’t stop&lt;/p&gt;

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

&lt;p&gt;Goroutines are the foundation of Go’s simplicity and power.&lt;br&gt;
Once you master them, you’ll start thinking in concurrent patterns — building systems that scale effortlessly.&lt;/p&gt;

&lt;p&gt;In upcoming posts, I’ll dive deeper into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context cancellation&lt;/li&gt;
&lt;li&gt;Pipelines&lt;/li&gt;
&lt;li&gt;Fan-out/Fan-in patterns&lt;/li&gt;
&lt;li&gt;Real-world concurrency debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✍️ Written by &lt;a href="https://dev.to/devto_with_yog"&gt;Yogesh Mathankar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 Modern MERN &amp;amp; Go developer passionate about building scalable systems and AI-integrated apps.&lt;/p&gt;

</description>
      <category>go</category>
      <category>backenddevelopment</category>
      <category>goroutine</category>
    </item>
    <item>
      <title>NestJS Expert Series – Part 5: API Gateway and Service Communication</title>
      <dc:creator>Yogesh Prasad</dc:creator>
      <pubDate>Mon, 06 Oct 2025 17:04:20 +0000</pubDate>
      <link>https://forem.com/devto_with_yog/nestjs-expert-series-part-5-api-gateway-and-service-communication-o10</link>
      <guid>https://forem.com/devto_with_yog/nestjs-expert-series-part-5-api-gateway-and-service-communication-o10</guid>
      <description>&lt;p&gt;Welcome back to the NestJS Expert Series! 👋&lt;br&gt;
In Part 4&lt;a href="https://dev.to/devto_with_yog/nestjs-expert-series-part-4-building-scalable-microservices-with-nestjs-and-message-queues-2iae"&gt;&lt;/a&gt;, we built scalable microservices with RabbitMQ.&lt;br&gt;
Now, it’s time to take the next step — integrating them with an API Gateway and service-to-service communication.&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Why Use an API Gateway?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When your app grows into multiple microservices (Auth, Users, Orders, Payments, etc.), clients shouldn’t need to know where each service lives.&lt;/p&gt;

&lt;p&gt;Instead, the API Gateway acts as a single entry point — handling:&lt;/p&gt;

&lt;p&gt;Authentication&lt;/p&gt;

&lt;p&gt;Routing requests to the right microservice&lt;/p&gt;

&lt;p&gt;Response aggregation&lt;/p&gt;

&lt;p&gt;Rate limiting, caching, logging&lt;/p&gt;

&lt;p&gt;This is the same principle used by Netflix, Uber, and Amazon for their distributed architectures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚙️ Step 1 – Setup a New API Gateway Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s create a separate NestJS project to act as the gateway:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nest new api-gateway&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, install the microservice package:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i @nestjs/microservices&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠 Step 2 – Connect the Gateway to Microservices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your app.module.ts of the API Gateway:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { GatewayController } from './gateway.controller';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'AUTH_SERVICE',
        transport: Transport.TCP,
        options: { host: 'localhost', port: 3001 },
      },
      {
        name: 'USER_SERVICE',
        transport: Transport.TCP,
        options: { host: 'localhost', port: 3002 },
      },
    ]),
  ],
  controllers: [GatewayController],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This defines two microservice connections:&lt;/p&gt;

&lt;p&gt;AUTH_SERVICE (for authentication)&lt;/p&gt;

&lt;p&gt;USER_SERVICE (for user-related operations)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧩 Step 3 – Build the Gateway Controller&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;gateway.controller.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller, Get, Inject, Post, Body } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';

@Controller('gateway')
export class GatewayController {
  constructor(
    @Inject('AUTH_SERVICE') private authClient: ClientProxy,
    @Inject('USER_SERVICE') private userClient: ClientProxy,
  ) {}

  @Post('login')
  async login(@Body() credentials: any) {
    return this.authClient.send({ cmd: 'login' }, credentials);
  }

  @Get('users')
  async getUsers() {
    return this.userClient.send({ cmd: 'get_users' }, {});
  }
}

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

&lt;/div&gt;



&lt;p&gt;✅ Here:&lt;/p&gt;

&lt;p&gt;The gateway sends messages to different microservices via TCP transport.&lt;/p&gt;

&lt;p&gt;Each microservice listens for specific message patterns and responds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎧 Step 4 – Listening in the Microservice&lt;/strong&gt;&lt;br&gt;
Example from user-service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class UserController {
  @MessagePattern({ cmd: 'get_users' })
  getUsers() {
    return [
      { id: 1, name: 'Yogesh' },
      { id: 2, name: 'Aditi' },
    ];
  }
}


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

&lt;/div&gt;



&lt;p&gt;Now, when the gateway sends { cmd: 'get_users' }, this microservice responds with a list of users.&lt;/p&gt;

&lt;p&gt;🧠 &lt;strong&gt;Step 5 – Add Authentication Middleware&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To protect routes at the gateway level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable, NestMiddleware } from '@nestjs/common';
import * as jwt from 'jsonwebtoken';

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  use(req: any, res: any, next: () =&amp;gt; void) {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) return res.status(401).json({ message: 'Unauthorized' });

    try {
      const decoded = jwt.verify(token, 'SECRET_KEY');
      req.user = decoded;
      next();
    } catch {
      return res.status(401).json({ message: 'Invalid token' });
    }
  }
}

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

&lt;/div&gt;



&lt;p&gt;This ensures centralized authentication — one verification at the gateway before forwarding requests to microservices.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Step 6 – Service Discovery (Optional)&lt;/strong&gt;&lt;br&gt;
For dynamic scaling, you can integrate Consul or Eureka to allow automatic service registration and discovery.&lt;br&gt;
This prevents hardcoding service URLs and enables horizontal scaling easily.&lt;/p&gt;

&lt;p&gt;🧭 Summary&lt;/p&gt;

&lt;p&gt;✅ Implemented a central API Gateway&lt;br&gt;
✅ Connected multiple microservices using TCP transport&lt;br&gt;
✅ Added authentication middleware&lt;br&gt;
✅ Laid the foundation for distributed, secure communication&lt;/p&gt;

&lt;p&gt;🔮 Coming Up Next (Part 6)&lt;/p&gt;

&lt;p&gt;In Part 6, we’ll take it even further:&lt;/p&gt;

&lt;p&gt;🔧 “Monitoring, Logging, and Observability in NestJS Microservices.”&lt;/p&gt;

&lt;p&gt;You’ll learn how to use Winston, Prometheus, and Grafana to track, debug, and optimize microservice performance.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>backend</category>
      <category>nestjs</category>
      <category>node</category>
    </item>
    <item>
      <title>🧩 NestJS Expert Series – Part 4: Building Scalable Microservices with NestJS and Message Queues</title>
      <dc:creator>Yogesh Prasad</dc:creator>
      <pubDate>Sun, 05 Oct 2025 14:00:24 +0000</pubDate>
      <link>https://forem.com/devto_with_yog/nestjs-expert-series-part-4-building-scalable-microservices-with-nestjs-and-message-queues-2iae</link>
      <guid>https://forem.com/devto_with_yog/nestjs-expert-series-part-4-building-scalable-microservices-with-nestjs-and-message-queues-2iae</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Introduction
&lt;/h2&gt;

&lt;p&gt;As your NestJS applications grow, scalability becomes a key challenge. Monolithic apps can become bottlenecks — hard to maintain, deploy, and scale.&lt;br&gt;
In this post, we’ll take the next step toward mastering backend architecture by implementing microservices in NestJS using message queues (RabbitMQ / Kafka).&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 What Are Microservices?
&lt;/h2&gt;

&lt;p&gt;Microservices architecture is a design approach where a large application is divided into smaller, independent services.&lt;br&gt;
Each service handles a specific business function and communicates with others through lightweight mechanisms — often a message broker.&lt;/p&gt;

&lt;p&gt;✅ Benefits:&lt;/p&gt;

&lt;p&gt;Independent deployment &amp;amp; scaling&lt;/p&gt;

&lt;p&gt;Fault isolation&lt;/p&gt;

&lt;p&gt;Technology flexibility&lt;/p&gt;

&lt;p&gt;Simplified development for large teams&lt;/p&gt;

&lt;p&gt;⚙️ Setting Up a Microservice in NestJS&lt;/p&gt;

&lt;p&gt;Let’s start with a basic setup for microservices in NestJS.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i @nestjs/microservices amqplib&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create a main.ts for your microservice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';

async function bootstrap() {
  const app = await NestFactory.createMicroservice&amp;lt;MicroserviceOptions&amp;gt;(AppModule, {
    transport: Transport.RMQ,
    options: {
      urls: ['amqp://localhost:5672'],
      queue: 'tasks_queue',
      queueOptions: { durable: false },
    },
  });

  await app.listen();
  console.log('Microservice is listening...');
}
bootstrap();


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

&lt;/div&gt;



&lt;p&gt;This creates a RabbitMQ-based microservice that listens for incoming messages from the tasks_queue.&lt;/p&gt;

&lt;p&gt;📡 Sending Messages from Another Service&lt;/p&gt;

&lt;p&gt;In your main (API Gateway) application, you can send messages to this queue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller, Post, Body } from '@nestjs/common';
import { ClientProxy, ClientProxyFactory, Transport } from '@nestjs/microservices';

@Controller('tasks')
export class TaskController {
  private client: ClientProxy;

  constructor() {
    this.client = ClientProxyFactory.create({
      transport: Transport.RMQ,
      options: {
        urls: ['amqp://localhost:5672'],
        queue: 'tasks_queue',
        queueOptions: { durable: false },
      },
    });
  }

  @Post()
  async createTask(@Body() taskData: any) {
    this.client.emit('task_created', taskData);
    return { message: 'Task sent to microservice successfully!' };
  }
}

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

&lt;/div&gt;



&lt;p&gt;🎧 Handling Messages in the Microservice&lt;/p&gt;

&lt;p&gt;Inside your microservice, handle the event using a simple listener:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller } from '@nestjs/common';
import { EventPattern, Payload } from '@nestjs/microservices';

@Controller()
export class TaskListener {
  @EventPattern('task_created')
  handleTaskCreated(@Payload() data: any) {
    console.log('Task received:', data);
  }
}

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

&lt;/div&gt;



&lt;p&gt;Now, when your API Gateway emits a task_created event, the microservice automatically consumes and processes it.&lt;/p&gt;

&lt;p&gt;🔁 Scaling with Message Queues&lt;/p&gt;

&lt;p&gt;Using message queues like RabbitMQ or Kafka enables you to:&lt;/p&gt;

&lt;p&gt;Distribute workloads evenly among multiple instances&lt;/p&gt;

&lt;p&gt;Ensure reliability (retry, acknowledgment)&lt;/p&gt;

&lt;p&gt;Achieve async processing for heavy tasks (emails, reports, ML jobs, etc.)&lt;/p&gt;

&lt;p&gt;NestJS handles all this natively — no extra boilerplate needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧱 Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;Background jobs (e.g., sending notifications)&lt;/p&gt;

&lt;p&gt;Transactional emails&lt;/p&gt;

&lt;p&gt;Payment processing&lt;/p&gt;

&lt;p&gt;Video transcoding&lt;/p&gt;

&lt;p&gt;Data sync between services&lt;/p&gt;

&lt;h2&gt;
  
  
  🧭 Best Practices
&lt;/h2&gt;

&lt;p&gt;Use DLQs (Dead Letter Queues) for failed messages.&lt;/p&gt;

&lt;p&gt;Keep messages idempotent.&lt;/p&gt;

&lt;p&gt;Add monitoring with Prometheus + Grafana.&lt;/p&gt;

&lt;p&gt;Ensure graceful shutdowns of microservices.&lt;/p&gt;

&lt;p&gt;Document your events for clear communication between teams.&lt;/p&gt;

&lt;p&gt;💡 Summary&lt;/p&gt;

&lt;p&gt;In this part, we explored how to:&lt;/p&gt;

&lt;p&gt;Build a NestJS microservice&lt;/p&gt;

&lt;p&gt;Use RabbitMQ for message communication&lt;/p&gt;

&lt;p&gt;Emit and listen to events between services&lt;/p&gt;

&lt;p&gt;Design scalable and resilient systems&lt;/p&gt;

&lt;p&gt;By combining NestJS with message brokers, you can architect truly enterprise-grade distributed systems.&lt;/p&gt;

&lt;p&gt;🧠 Coming Up Next (Part 5)&lt;/p&gt;

&lt;p&gt;In Part 5, we’ll dive into API Gateway and Service Discovery with NestJS, where we’ll handle inter-service communication and authentication across microservices.&lt;/p&gt;

</description>
      <category>news</category>
      <category>microservices</category>
      <category>backend</category>
      <category>node</category>
    </item>
    <item>
      <title>🔑 NestJS Expert Series (Part 3): Authentication &amp; Authorization with JWT and Guards your</title>
      <dc:creator>Yogesh Prasad</dc:creator>
      <pubDate>Sat, 04 Oct 2025 14:45:24 +0000</pubDate>
      <link>https://forem.com/devto_with_yog/nestjs-expert-series-part-3-authentication-authorization-with-jwt-and-guards-your-1cgo</link>
      <guid>https://forem.com/devto_with_yog/nestjs-expert-series-part-3-authentication-authorization-with-jwt-and-guards-your-1cgo</guid>
      <description>&lt;p&gt;Welcome back to the NestJS Expert Series! 🎉&lt;br&gt;
In Part &lt;a href="https://dev.to/devto_with_yog/nestjs-expert-series-part-2-database-integration-with-prisma-typeorm-ica"&gt;https://dev.to/devto_with_yog/nestjs-expert-series-part-2-database-integration-with-prisma-typeorm-ica&lt;/a&gt;, we integrated our NestJS app with a database using Prisma and TypeORM.&lt;/p&gt;

&lt;p&gt;Now it’s time to secure our application with Authentication (who you are) and Authorization (what you can do).&lt;/p&gt;

&lt;p&gt;In this article, we’ll build a JWT-based authentication system and use Guards to implement role-based access control.&lt;/p&gt;



&lt;p&gt;⚡ Why JWT for Authentication?&lt;/p&gt;

&lt;p&gt;JWT (JSON Web Token) is a compact, URL-safe token format widely used for stateless authentication.&lt;/p&gt;

&lt;p&gt;✅ Stateless – No need to store session data on the server.&lt;br&gt;
✅ Scalable – Works well in distributed systems.&lt;br&gt;
✅ Cross-platform – Can be used by web, mobile, and microservices.&lt;/p&gt;



&lt;p&gt;📦 Step 1: Install Required Packages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🛠️ Step 2: Auth Module Setup&lt;/p&gt;

&lt;p&gt;Generate an auth module, service, and controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
nest g module auth
nest g service auth
nest g controller auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;👤 Step 3: User Entity (with Prisma Example)&lt;/p&gt;

&lt;p&gt;If you’re using Prisma, update your schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model User {
  id       Int    @id @default(autoincrement())
  email    String @unique
  password String
  role     String @default("user")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx prisma migrate dev --name add_user_model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🔑 Step 4: Auth Service (Register &amp;amp; Login)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcrypt';

@Injectable()
export class AuthService {
  constructor(private jwtService: JwtService) {}

  async hashPassword(password: string): Promise&amp;lt;string&amp;gt; {
    return bcrypt.hash(password, 10);
  }

  async validatePassword(password: string, hash: string): Promise&amp;lt;boolean&amp;gt; {
    return bcrypt.compare(password, hash);
  }

  async generateToken(user: { id: number; email: string; role: string }) {
    return this.jwtService.sign({ sub: user.id, email: user.email, role: user.role });
  }
}

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

&lt;/div&gt;






&lt;p&gt;📜 Step 5: Auth Controller&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller, Post, Body } from '@nestjs/common';
import { AuthService } from './auth.service';

@Controller('auth')
export class AuthController {
  constructor(private authService: AuthService) {}

  @Post('register')
  async register(@Body() body: { email: string; password: string }) {
    const hashed = await this.authService.hashPassword(body.password);
    // Save user to DB with hashed password
    return { message: 'User registered successfully' };
  }

  @Post('login')
  async login(@Body() body: { email: string; password: string }) {
    // Find user in DB and validate password
    // If valid, generate token
    return { access_token: await this.authService.generateToken({ id: 1, email: body.email, role: 'user' }) };
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🛡️ Step 6: Guards for Authorization&lt;/p&gt;

&lt;p&gt;NestJS Guards decide whether a request should proceed or not.&lt;/p&gt;

&lt;p&gt;Create a roles.guard.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.get&amp;lt;string[]&amp;gt;('roles', context.getHandler());
    if (!requiredRoles) return true;

    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.includes(user.role);
  }
}

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

&lt;/div&gt;



&lt;p&gt;Use a custom decorator roles.decorator.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) =&amp;gt; SetMetadata('roles', roles);

Apply it in a controller:

import { Controller, Get, UseGuards } from '@nestjs/common';
import { Roles } from './roles.decorator';
import { RolesGuard } from './roles.guard';

@Controller('admin')
export class AdminController {
  @Get()
  @Roles('admin')
  @UseGuards(RolesGuard)
  findAdminData() {
    return { secret: 'This is admin-only data' };
  }
}

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

&lt;/div&gt;






&lt;p&gt;🚀 Conclusion&lt;/p&gt;

&lt;p&gt;✅ We built JWT-based authentication.&lt;/p&gt;

&lt;p&gt;✅ We secured routes with Guards and Role-based Authorization.&lt;/p&gt;

&lt;p&gt;✅ We now have the foundation for a secure, multi-user NestJS application.&lt;/p&gt;

&lt;p&gt;In the next part, we’ll tackle Validation &amp;amp; Error Handling with Pipes and Filters to make our APIs more robust.&lt;/p&gt;




&lt;p&gt;💡 If you found this helpful, drop a ❤️ on Dev.to and follow me for Part 4 of the NestJS Expert Series.&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>node</category>
      <category>backend</category>
      <category>jwt</category>
    </item>
    <item>
      <title>NestJS Expert Series (Part 2): Database Integration with Prisma &amp; TypeORM</title>
      <dc:creator>Yogesh Prasad</dc:creator>
      <pubDate>Fri, 03 Oct 2025 17:07:35 +0000</pubDate>
      <link>https://forem.com/devto_with_yog/nestjs-expert-series-part-2-database-integration-with-prisma-typeorm-ica</link>
      <guid>https://forem.com/devto_with_yog/nestjs-expert-series-part-2-database-integration-with-prisma-typeorm-ica</guid>
      <description>&lt;p&gt;Welcome back to the NestJS Expert Series! 🎉&lt;br&gt;
In &lt;a href="https://dev.to/devto_with_yog/mastering-nestjs-a-modern-approach-to-building-scalable-nodejs-applications-l6n"&gt;Part 1&lt;/a&gt;,we built a simple CRUD API using NestJS fundamentals—Modules, Controllers, and Services.&lt;/p&gt;

&lt;p&gt;But any real-world application needs persistent storage. That’s where databases come in.&lt;/p&gt;

&lt;p&gt;In this article, we’ll integrate databases with NestJS using two popular ORMs:&lt;/p&gt;

&lt;p&gt;Prisma – Modern, type-safe ORM with great DX.&lt;/p&gt;

&lt;p&gt;TypeORM – Mature ORM used widely in enterprise projects.&lt;/p&gt;

&lt;p&gt;By the end, you’ll be able to hook up your NestJS app to a PostgreSQL database (the same steps apply for MySQL or SQLite).&lt;/p&gt;

&lt;p&gt;⚡ Step 1: Setting Up a Database&lt;/p&gt;

&lt;p&gt;For this guide, let’s use PostgreSQL. If you have Docker installed:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run --name nest-postgres -e POSTGRES_PASSWORD=admin -e POSTGRES_USER=admin -e POSTGRES_DB=tasks -p 5432:5432 -d postgres&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;📦 Step 2: Adding Prisma to NestJS&lt;br&gt;
&lt;code&gt;npm install prisma --save-dev&lt;br&gt;
npm install @prisma/client&lt;br&gt;
npx prisma init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This creates a prisma/schema.prisma file. Define a simple Task model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model Task {
  id        Int      @id @default(autoincrement())
  title     String
  isCompleted Boolean @default(false)
  createdAt DateTime @default(now())
}

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

&lt;/div&gt;



&lt;p&gt;Run migrations:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx prisma migrate dev --name init&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
🛠️ Step 3: Using Prisma in NestJS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Create a Prisma service:

nest g service prisma`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;prisma.service.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
  async onModuleInit() {
    await this.$connect();
  }
  async onModuleDestroy() {
    await this.$disconnect();
  }
}


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

&lt;/div&gt;



&lt;p&gt;Now inject it into your TasksService:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';

@Injectable()
export class TasksService {
  constructor(private prisma: PrismaService) {}

  findAll() {
    return this.prisma.task.findMany();
  }

  create(title: string) {
    return this.prisma.task.create({ data: { title } });
  }

  update(id: number, isCompleted: boolean) {
    return this.prisma.task.update({
      where: { id },
      data: { isCompleted },
    });
  }

  delete(id: number) {
    return this.prisma.task.delete({ where: { id } });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your Tasks API is connected to PostgreSQL with Prisma 🎉.&lt;/p&gt;

&lt;p&gt;🔄 Alternative: TypeORM with NestJS&lt;/p&gt;

&lt;p&gt;Some teams still prefer TypeORM for its flexibility. Here’s the quick setup:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install @nestjs/typeorm typeorm pg&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add it to app.module.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Task } from './tasks/task.entity';
import { TasksModule } from './tasks/tasks.module';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: 'localhost',
      port: 5432,
      username: 'admin',
      password: 'admin',
      database: 'tasks',
      entities: [Task],
      synchronize: true,
    }),
    TasksModule,
  ],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;task.entity.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity()
export class Task {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @Column({ default: false })
  isCompleted: boolean;
}


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

&lt;/div&gt;



&lt;p&gt;Inject repositories with @InjectRepository(Task) in your services.&lt;/p&gt;

&lt;p&gt;🚀 Conclusion&lt;/p&gt;

&lt;p&gt;Prisma gives you type safety and an amazing developer experience.&lt;/p&gt;

&lt;p&gt;TypeORM is feature-rich and widely adopted.&lt;/p&gt;

&lt;p&gt;👉 Choose Prisma if you want speed + DX.&lt;br&gt;
👉 Choose TypeORM if you need complex queries and legacy support.&lt;/p&gt;

&lt;p&gt;Now your NestJS app can persist data into a database like a real-world backend.&lt;/p&gt;

&lt;p&gt;In the next part of the series, we’ll tackle Authentication &amp;amp; Authorization with JWTs and Guards.&lt;/p&gt;

&lt;p&gt;💡 Found this useful? Drop a ❤️ on Dev.to and follow me for Part 3 of the NestJS Expert Series.&lt;/p&gt;

</description>
      <category>database</category>
      <category>typescript</category>
      <category>tutorial</category>
      <category>node</category>
    </item>
    <item>
      <title>Ulaa: India’s Next Browser for Developers and Privacy Enthusiasts 🚀</title>
      <dc:creator>Yogesh Prasad</dc:creator>
      <pubDate>Tue, 30 Sep 2025 12:35:41 +0000</pubDate>
      <link>https://forem.com/devto_with_yog/ulaa-indias-next-browser-for-developers-and-privacy-enthusiasts-516o</link>
      <guid>https://forem.com/devto_with_yog/ulaa-indias-next-browser-for-developers-and-privacy-enthusiasts-516o</guid>
      <description>&lt;p&gt;Ulaa: India’s Next Browser for Developers and Privacy Enthusiasts 🚀&lt;/p&gt;

&lt;p&gt;When it comes to web browsers, we usually hear the same big names: Chrome, Firefox, Edge, Brave. Most of them are either from the US or Europe, with data policies that often raise questions in countries like India.&lt;/p&gt;

&lt;p&gt;But now, we finally have a strong Made-in-India alternative: Ulaa by Zoho.&lt;br&gt;
Ulaa means journey in Tamil — and it truly feels like the beginning of India’s journey toward building a privacy-first, developer-friendly browser that competes with global giants.&lt;/p&gt;

&lt;p&gt;In this blog, I’ll share my experience of using Ulaa as a developer in India, what makes it stand out, and why it deserves to be called India’s next browser.&lt;/p&gt;

&lt;p&gt;🌏 Why India Needs Its Own Browser&lt;/p&gt;

&lt;p&gt;India is rapidly moving toward data sovereignty — ensuring that user data is stored, managed, and protected within the country. With 1.4 billion people, the need for a browser that is built in India, for Indians, with global standards is huge.&lt;/p&gt;

&lt;p&gt;Here’s why:&lt;/p&gt;

&lt;p&gt;Dependence on foreign tech → Most browsers rely on US-based companies.&lt;/p&gt;

&lt;p&gt;Privacy concerns → Data is often collected, tracked, and monetized.&lt;/p&gt;

&lt;p&gt;Local innovation → India has the talent to build world-class software — Zoho’s success proves it.&lt;/p&gt;

&lt;p&gt;Ulaa isn’t just another Chromium fork. It’s India’s shot at redefining the browser space with privacy, productivity, and ethical design.&lt;/p&gt;

&lt;p&gt;⚡ First Impressions as a Developer&lt;/p&gt;

&lt;p&gt;As a developer, here’s what stood out when I started using Ulaa:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multiple Browsing Modes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Unlike Chrome or Firefox, Ulaa lets you switch modes:&lt;/p&gt;

&lt;p&gt;Work Mode – Isolate projects and keep professional sessions separate.&lt;/p&gt;

&lt;p&gt;Developer Mode – Tailored for debugging and testing.&lt;/p&gt;

&lt;p&gt;Kids Mode – Safe browsing for children.&lt;/p&gt;

&lt;p&gt;Personal Mode – Private browsing without trackers.&lt;/p&gt;

&lt;p&gt;Open Season Mode – Compatibility for sites that force cookies/trackers.&lt;/p&gt;

&lt;p&gt;This separation is a blessing for developers in India juggling client projects, side hustles, and personal life — all in one machine.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Built-in Privacy Features&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ad &amp;amp; tracker blocking by default.&lt;/p&gt;

&lt;p&gt;DNS-level blocking for malicious domains.&lt;/p&gt;

&lt;p&gt;Zero hidden sync with foreign servers.&lt;/p&gt;

&lt;p&gt;In a time when digital privacy is becoming as important as financial privacy, Ulaa stands tall.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Productivity-First Design&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tab grouping &amp;amp; session isolation → Perfect for handling multiple clients.&lt;/p&gt;

&lt;p&gt;Built-in screen capture &amp;amp; annotations → Share quick feedback with teams.&lt;/p&gt;

&lt;p&gt;Reader mode → Distraction-free learning, ideal for reading Indian govt policies, dev blogs, or long-form docs.&lt;/p&gt;

&lt;p&gt;These small details feel made for real working professionals in India.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Chrome&lt;/th&gt;
&lt;th&gt;Brave&lt;/th&gt;
&lt;th&gt;Firefox&lt;/th&gt;
&lt;th&gt;Ulaa (India)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Origin&lt;/td&gt;
&lt;td&gt;USA&lt;/td&gt;
&lt;td&gt;USA&lt;/td&gt;
&lt;td&gt;USA&lt;/td&gt;
&lt;td&gt;🇮🇳 India&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privacy-first&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multiple browsing modes&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer workflow mode&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in productivity&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ethical data use&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With Ulaa, we finally have a homegrown browser that competes globally.&lt;/p&gt;

&lt;p&gt;💡 Why Developers in India Should Care&lt;/p&gt;

&lt;p&gt;Local trust → Built in India, by Zoho (a trusted SaaS giant).&lt;/p&gt;

&lt;p&gt;Better debugging → Separate workflows for development and testing.&lt;/p&gt;

&lt;p&gt;No vendor lock-in → Your data isn’t tied to foreign companies.&lt;/p&gt;

&lt;p&gt;Project-friendly → Great for freelancers, startups, and agencies in India handling multiple clients.&lt;/p&gt;

&lt;p&gt;🚀 Final Thoughts&lt;/p&gt;

&lt;p&gt;Ulaa may be new, but it’s a serious contender.&lt;/p&gt;

&lt;p&gt;It respects Indian users’ privacy.&lt;/p&gt;

&lt;p&gt;It promotes data sovereignty.&lt;/p&gt;

&lt;p&gt;It’s designed with developers and productivity in mind.&lt;/p&gt;

&lt;p&gt;Is it perfect? Not yet — the extension ecosystem still needs to grow, and some sites behave better in "Open Season" mode. But as India’s first big step in the browser space, Ulaa is both promising and refreshing.&lt;/p&gt;

&lt;p&gt;✅ Takeaway&lt;/p&gt;

&lt;p&gt;If you want to support a Made-in-India browser that:&lt;/p&gt;

&lt;p&gt;Respects your privacy,&lt;/p&gt;

&lt;p&gt;Boosts your productivity,&lt;/p&gt;

&lt;p&gt;And gives developers thoughtful tools…&lt;/p&gt;

&lt;p&gt;👉 Give Ulaa a try. It might just be India’s answer to Chrome and Brave.&lt;/p&gt;

&lt;p&gt;💬 Over to you: Do you think India can build a global tech product in the browser space? Have you tried Ulaa yet?&lt;/p&gt;

</description>
      <category>newbrowser</category>
      <category>ulaa</category>
      <category>indian</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Mastering NestJS: A Modern Approach to Building Scalable Node.js Applications</title>
      <dc:creator>Yogesh Prasad</dc:creator>
      <pubDate>Tue, 30 Sep 2025 08:54:12 +0000</pubDate>
      <link>https://forem.com/devto_with_yog/mastering-nestjs-a-modern-approach-to-building-scalable-nodejs-applications-l6n</link>
      <guid>https://forem.com/devto_with_yog/mastering-nestjs-a-modern-approach-to-building-scalable-nodejs-applications-l6n</guid>
      <description>&lt;p&gt;🚀 Mastering NestJS: A Modern Approach to Building Scalable Node.js Applications&lt;/p&gt;

&lt;p&gt;When it comes to building scalable and maintainable backend applications, developers often find themselves struggling with vanilla Node.js and Express. While they are powerful, they lack structure when your project grows beyond a few routes.&lt;/p&gt;

&lt;p&gt;This is where NestJS comes in—a progressive Node.js framework that provides an opinionated yet flexible architecture out of the box, enabling developers to build enterprise-grade applications with confidence.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore why NestJS is becoming the go-to framework for Node.js development and how you can use it to architect applications like an expert.&lt;/p&gt;




&lt;p&gt;🔑 Why NestJS?&lt;/p&gt;

&lt;p&gt;NestJS is built on top of Express (or optionally Fastify) and leverages TypeScript to enforce clean code structure.&lt;/p&gt;

&lt;p&gt;Here’s what makes it stand out:&lt;/p&gt;

&lt;p&gt;Opinionated Architecture – Inspired by Angular, it uses modules, controllers, and providers to keep code organized.&lt;/p&gt;

&lt;p&gt;Dependency Injection – Built-in support for DI ensures testability and reusability.&lt;/p&gt;

&lt;p&gt;Microservices Ready – Built-in support for gRPC, Kafka, RabbitMQ, and more.&lt;/p&gt;

&lt;p&gt;Scalable Monoliths &amp;amp; Microservices – Perfect for both startups and enterprises.&lt;/p&gt;

&lt;p&gt;Strong Type Safety – Leverages TypeScript for better developer experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ The Core Building Blocks
&lt;/h2&gt;

&lt;p&gt;Before we dive into code, let’s understand the NestJS building blocks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Modules – Logical units of your app (like UsersModule, AuthModule).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Controllers – Handle incoming requests and return responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Providers (Services) – Business logic and reusable code live here.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependency Injection – Services are injected where needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Middleware, Guards, Interceptors, and Pipes – Powerful tools for cross-cutting concerns like validation, logging, and authentication.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⚡ Quick Start Example: A CRUD API&lt;/p&gt;

&lt;p&gt;Let’s build a simple Tasks API to demonstrate NestJS fundamentals.&lt;br&gt;
`&lt;/p&gt;
&lt;h1&gt;
  
  
  Install NestJS CLI
&lt;/h1&gt;

&lt;p&gt;npm i -g @nestjs/cli&lt;/p&gt;
&lt;h1&gt;
  
  
  Create a new project
&lt;/h1&gt;

&lt;p&gt;nest new tasks-api`&lt;/p&gt;

&lt;p&gt;Now, let’s create a Tasks module:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nest g module tasks&lt;br&gt;
nest g controller tasks&lt;br&gt;
nest g service tasks&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;tasks.service.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`import { Injectable } from '@nestjs/common';

interface Task {
  id: number;
  title: string;
  isCompleted: boolean;
}

@Injectable()
export class TasksService {
  private tasks: Task[] = [];

  findAll(): Task[] {
    return this.tasks;
  }

  create(title: string): Task {
    const task: Task = {
      id: Date.now(),
      title,
      isCompleted: false,
    };
    this.tasks.push(task);
    return task;
  }

  update(id: number, isCompleted: boolean): Task {
    const task = this.tasks.find((t) =&amp;gt; t.id === id);
    if (task) {
      task.isCompleted = isCompleted;
    }
    return task;
  }

  delete(id: number): void {
    this.tasks = this.tasks.filter((t) =&amp;gt; t.id !== id);
  }
}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;tasks.controller.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller, Get, Post, Body, Param, Patch, Delete } from '@nestjs/common';
import { TasksService } from './tasks.service';

@Controller('tasks')
export class TasksController {
  constructor(private readonly tasksService: TasksService) {}

  @Get()
  findAll() {
    return this.tasksService.findAll();
  }

  @Post()
  create(@Body('title') title: string) {
    return this.tasksService.create(title);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body('isCompleted') isCompleted: boolean) {
    return this.tasksService.update(+id, isCompleted);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    this.tasksService.delete(+id);
    return { message: 'Task deleted' };
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With just a few lines of code, you now have a fully working CRUD API with clean architecture.&lt;/p&gt;




&lt;p&gt;🛡️ &lt;/p&gt;

&lt;h2&gt;
  
  
  Going Pro: Advanced Features
&lt;/h2&gt;

&lt;p&gt;To really become an expert in NestJS, you need to go beyond CRUD. Here’s what you should explore:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Authentication &amp;amp; Authorization – Use Guards and Passport.js strategies for role-based access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validation – Leverage Pipes and the class-validator library for request validation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logging &amp;amp; Monitoring – Implement custom Interceptors and connect with tools like Prometheus or ELK stack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Integration – Use TypeORM, Prisma, or Sequelize seamlessly with NestJS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microservices &amp;amp; Event-Driven Architecture – Scale your app using message brokers like Kafka or RabbitMQ.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL Support – Build APIs with GraphQL and schema-first or code-first approaches.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing – Take advantage of Nest’s built-in unit and e2e testing support.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🌍&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NestJS is being used in production by companies across fintech, e-commerce, SaaS, and gaming. Some popular scenarios include:&lt;/li&gt;
&lt;li&gt;Banking &amp;amp; Fintech Apps – Secure APIs with auditing and transaction handling.&lt;/li&gt;
&lt;li&gt;E-commerce Platforms – Scalable APIs with microservices.&lt;/li&gt;
&lt;li&gt;SaaS Products – Multi-tenant apps with modular architecture.&lt;/li&gt;
&lt;li&gt;IoT &amp;amp; Event-Driven Systems – Real-time communication with microservices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🚀 &lt;/p&gt;

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

&lt;p&gt;NestJS is not just another Node.js framework—it’s a complete architecture solution for building scalable, testable, and enterprise-ready applications.&lt;/p&gt;

&lt;p&gt;By mastering modules, controllers, services, guards, and interceptors, you’ll be equipped to build backends that can scale from MVPs to complex microservices. &lt;/p&gt;

</description>
      <category>backend</category>
      <category>javascript</category>
      <category>node</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
