<?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: Jayvee Ramos</title>
    <description>The latest articles on DEV Community by Jayvee Ramos (@techjayvee).</description>
    <link>https://dev.to/techjayvee</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%2F1156142%2F33689a5a-14c1-4fc9-bfdc-23dd38138a6b.jpeg</url>
      <title>DEV Community: Jayvee Ramos</title>
      <link>https://dev.to/techjayvee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/techjayvee"/>
    <language>en</language>
    <item>
      <title>Handling Data Updates and Expirations in Redis for Enhanced Cache Management</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Fri, 17 Nov 2023 03:03:22 +0000</pubDate>
      <link>https://dev.to/techjayvee/handling-data-updates-and-expirations-in-redis-for-enhanced-cache-management-43mi</link>
      <guid>https://dev.to/techjayvee/handling-data-updates-and-expirations-in-redis-for-enhanced-cache-management-43mi</guid>
      <description>&lt;h2&gt;
  
  
  Handling Data Updates and Expirations in Redis for Enhanced Cache Management
&lt;/h2&gt;

&lt;p&gt;Welcome back to our Redis and Express optimization series! In our previous tutorials, we explored setting up Redis, basic operations like adding and retrieving data, and optimizing data retrieval using Redis caching. Now, let's delve into a crucial aspect of cache management—handling data updates and expirations.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Challenge of Data Updates:
&lt;/h2&gt;

&lt;p&gt;In a dynamic application, data is constantly evolving. Consider a scenario where a user edits their post. In your database, the post gets updated to reflect the change. However, with our current caching strategy, the outdated post information persists in Redis.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Quick Recap of Redis Key-Value Storage:
&lt;/h2&gt;

&lt;p&gt;Redis, being a key-value store, retains data in memory. For instance, the key "post1" might be associated with the value "I like cars." But what if a user updates their post to "I don't like cars"? How can we ensure our cache reflects this change?&lt;/p&gt;




&lt;h2&gt;
  
  
  Strategies for Handling Data Updates:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Immediate Update Approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a user updates their post, we can immediately update the corresponding Redis cache using client.set. This approach guarantees that our cache is always synchronized with the latest data in the database.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Expiration-based Approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alternatively, we can set an expiration time for each cache entry. After a specified period (e.g., 10 seconds), Redis automatically clears the cache. Subsequent requests trigger a fresh data retrieval, ensuring updated information is fetched.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Combining Strategies for Robust Cache Management:
&lt;/h2&gt;

&lt;p&gt;The ideal approach often involves a combination of both strategies. Immediate updates ensure consistency in real-time, while expirations act as a safety net, preventing outdated data from persisting indefinitely.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementing Expirations in Redis:
&lt;/h2&gt;

&lt;p&gt;Let's explore the expiration approach. When setting a value in Redis, we can specify its time-to-live (TTL) using the EX parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Example: Setting a value with a 10-second expiration
client.setEx('post1', 'I like cars', 'EX', 10);

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

&lt;/div&gt;



&lt;p&gt;This code ensures that the key "post1" will expire and be removed from the cache after 10 seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Demonstration:
&lt;/h2&gt;

&lt;p&gt;Let's observe this in action. In our example, we set a cache expiration of 10 seconds for a post. After this period, Redis automatically removes the entry, prompting a fresh data retrieval.&lt;/p&gt;




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

&lt;p&gt;Handling data updates and expirations is crucial for maintaining a reliable and responsive cache system. Whether you opt for immediate updates, expirations, or a blend of both, understanding these strategies ensures your application remains performant and up-to-date.&lt;/p&gt;

&lt;p&gt;In our next tutorial, we'll explore more advanced features of Redis, so stay tuned for further Redis and Express optimization insights!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>redis</category>
      <category>caching</category>
    </item>
    <item>
      <title>Optimizing Data Retrieval with Redis Caching in Your Express App</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Fri, 17 Nov 2023 03:03:12 +0000</pubDate>
      <link>https://dev.to/techjayvee/optimizing-data-retrieval-with-redis-caching-in-your-express-app-1l15</link>
      <guid>https://dev.to/techjayvee/optimizing-data-retrieval-with-redis-caching-in-your-express-app-1l15</guid>
      <description>&lt;h2&gt;
  
  
  Optimizing Data Retrieval with Redis Caching in Your Express App
&lt;/h2&gt;

&lt;p&gt;In our previous tutorials, we successfully set up Redis and explored basic operations like adding and retrieving data. Now, let's take our application to the next level by incorporating Redis caching to dramatically improve data retrieval speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Simulating Real-World Scenarios:
&lt;/h2&gt;

&lt;p&gt;In a real-world scenario, our application may need to fetch data from an external API or a database. To simulate this, we'll make an HTTP request to the &lt;a href="https://jsonplaceholder.typicode.com/"&gt;JSONPlaceholder API&lt;/a&gt;, a free API for testing and prototyping. This API allows us to retrieve posts using a dynamic post ID.&lt;/p&gt;

&lt;p&gt;Here's a glimpse of the Express route:&lt;/p&gt;

&lt;p&gt;make sure to install &lt;code&gt;axios&lt;/code&gt; just run this command on your terminal &lt;code&gt;npm install axios&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

// index.js

const express = require("express");
const axios = require("axios");
const redis = require("redis");

const app = express();
const port = 8080;

const client = redis.createClient({
  host: "127.0.0.1",
  port: 6379,
});

client.on("error", (error) =&amp;gt; {
  if (error) {
    console.error("ERROR***", error);
  } else {
    console.log("Redis connect.");
  }
});

(async () =&amp;gt; {
  client.connect();
})();

app.use(express.json());

// Endpoint to add data to Redis
app.post("/", async (req, res) =&amp;gt; {
  const { key, value } = req.body;

  // Set data in Redis
  const response = await client.set(key, value);

  // Respond with the Redis response
  res.json(response);
});

app.get("/:key", async (req, res) =&amp;gt; {
  const { key } = req.params;

  // Get data from Redis
  const value = await client.get(key);

  // Respond with the Redis value
  res.json({ key, value });
});

app.get("/existing/:key", async (req, res) =&amp;gt; {
  const { key } = req.params;
  // Check if data exists in Redis
  const redisData = await client.get(key);

  if (redisData) {
    // If data is in Redis, return it
    res.json({ key, redisData });
  } else {
    // If not, interact with the database and store the data in Redis
    const databaseData = await fetchDataFromDatabase(key);
    await client.set(key, databaseData);

    // Return the data fetched from the database
    res.json({ key, databaseData });
  }
});

// Endpoint to get posts from JSONPlaceholder API
app.get("/posts/:id", async (req, res) =&amp;gt; {
  const id = req.params.id;

  // Check if the post is cached
  const cachedPost = await client.get(`post-${id}`);

  if (cachedPost) {
    // If cached, return the data
    return res.json(JSON.parse(cachedPost));
  }

  // If not cached, make an HTTP request to JSONPlaceholder API
  const response = await axios.get(
    `https://jsonplaceholder.typicode.com/posts/${id}`
  );
  const postData = response.data;

  // Cache the retrieved data in Redis
  await client.set(`post-${id}`, JSON.stringify(postData));

  // Return the retrieved data
  res.json(postData);
});

app.listen(port, () =&amp;gt; {
  console.log(`Now listening on port ${port}`);
});

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Leveraging Redis Caching for Faster Responses:
&lt;/h2&gt;

&lt;p&gt;Now, let's break down the logic:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We check if the requested post is already cached in Redis using the key post-${id}.&lt;/li&gt;
&lt;li&gt;If the post is cached, we retrieve and return it, avoiding the need for an external API request.&lt;/li&gt;
&lt;li&gt;If not cached, we make an HTTP request to the JSONPlaceholder API to get the post data.&lt;/li&gt;
&lt;li&gt;We cache the retrieved data in Redis for future use.&lt;/li&gt;
&lt;li&gt;Finally, we return the post data.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Enhancing Speed with Redis Cache:
&lt;/h2&gt;

&lt;p&gt;By using Redis caching, we've significantly optimized our application. The first request to an uncached post might take some time due to the API call, but subsequent requests for the same post are lightning-fast, thanks to the cached data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Handling Data Updates:
&lt;/h2&gt;

&lt;p&gt;In real-world applications, we must consider how to handle data updates. If a post gets updated or deleted, we need to ensure our cache is updated accordingly. This often involves implementing cache invalidation or expiration strategies.&lt;/p&gt;




&lt;p&gt;In our next section, we'll explore strategies for handling data updates in a Redis-cached environment. Stay tuned for more Redis and Express optimization tips!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>redis</category>
      <category>caching</category>
    </item>
    <item>
      <title>Adding and Retrieving Data with Redis in Your Express Application</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Fri, 17 Nov 2023 03:02:56 +0000</pubDate>
      <link>https://dev.to/techjayvee/adding-and-retrieving-data-with-redis-in-your-express-application-1le7</link>
      <guid>https://dev.to/techjayvee/adding-and-retrieving-data-with-redis-in-your-express-application-1le7</guid>
      <description>&lt;p&gt;Welcome back to our Redis and Express tutorial series! In the previous sections, we set up Redis on our local machine and established the foundations of our Express.js application. Now, let's dive into the exciting part – adding and retrieving data using Redis.&lt;/p&gt;




&lt;h2&gt;
  
  
  Adding Data to Redis:
&lt;/h2&gt;

&lt;p&gt;To add data to Redis, we'll create a new endpoint that accepts a POST request. Here's how you can do it:&lt;br&gt;
&lt;/p&gt;

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

// index.js

const express = require("express");
const redis = require("redis");

const app = express();
const port = 8080;

const client = redis.createClient({
  host: "127.0.0.1",
  port: 6379,
});

client.on("error", (error) =&amp;gt; {
  if (error) {
    console.error("ERROR***", error);
  } else {
    console.log("Redis connect.");
  }
});

(async () =&amp;gt; {
  client.connect();
})();

app.use(express.json());

// Endpoint to add data to Redis
app.post("/", async (req, res) =&amp;gt; {
  const { key, value } = req.body;

  // Set data in Redis
  const response = await client.set(key, value);

  // Respond with the Redis response
  res.json(response);
});

app.listen(port, () =&amp;gt; {
  console.log(`Now listening on port ${port}`);
});


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

&lt;/div&gt;






&lt;p&gt;Now, you can use Postman or any other API testing tool to send a POST request to &lt;a href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt; with a JSON body containing a key and value. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "key": "post",
  "value": "This is a cool course"
}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Retrieving Data from Redis:
&lt;/h2&gt;

&lt;p&gt;To retrieve data, we'll create another endpoint that accepts a GET request. Here's how you can implement it:&lt;br&gt;
&lt;/p&gt;

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

const express = require("express");
const redis = require("redis");

const app = express();
const port = 8080;

const client = redis.createClient({
  host: "127.0.0.1",
  port: 6379,
});

client.on("error", (error) =&amp;gt; {
  if (error) {
    console.error("ERROR***", error);
  } else {
    console.log("Redis connect.");
  }
});

(async () =&amp;gt; {
  client.connect();
})();

app.use(express.json());

// Endpoint to add data to Redis
app.post("/", async (req, res) =&amp;gt; {
  const { key, value } = req.body;

  // Set data in Redis
  const response = await client.set(key, value);

  // Respond with the Redis response
  res.json(response);
});

app.get("/:key", async (req, res) =&amp;gt; {
  const { key } = req.params;

  // Get data from Redis
  const value = await client.get(key);

  // Respond with the Redis value
  res.json({ key, value });
});

app.listen(port, () =&amp;gt; {
  console.log(`Now listening on port ${port}`);
});

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

&lt;/div&gt;






&lt;p&gt;Now, you can send a GET request to &lt;a href="http://localhost:880"&gt;http://localhost:880&lt;/a&gt; with a JSON body containing the key you want to retrieve. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "key": "post"
}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Scenario: Interacting with Database and Redis:
&lt;/h2&gt;

&lt;p&gt;In a real-world scenario, we want to check if the data exists in Redis before interacting with the database. If the data is in Redis, we return it; otherwise, we fetch it from the database, store it in Redis for future use, and then return it. Here's a sneak peek into our next section:&lt;br&gt;
&lt;/p&gt;

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

const express = require("express");
const redis = require("redis");

const app = express();
const port = 8080;

const client = redis.createClient({
  host: "127.0.0.1",
  port: 6379,
});

client.on("error", (error) =&amp;gt; {
  if (error) {
    console.error("ERROR***", error);
  } else {
    console.log("Redis connect.");
  }
});

(async () =&amp;gt; {
  client.connect();
})();

app.use(express.json());

// Endpoint to add data to Redis
app.post("/", async (req, res) =&amp;gt; {
  const { key, value } = req.body;

  // Set data in Redis
  const response = await client.set(key, value);

  // Respond with the Redis response
  res.json(response);
});

app.get("/:key", async (req, res) =&amp;gt; {
  const { key } = req.params;

  // Get data from Redis
  const value = await client.get(key);

  // Respond with the Redis value
  res.json({ key, value });
});

app.get("/existing/:key", async (req, res) =&amp;gt; {
  const { key } = req.params;
  // Check if data exists in Redis
  const redisData = await client.get(key);

  if (redisData) {
    // If data is in Redis, return it
    res.json({ key, redisData });
  } else {
    // If not, interact with the database and store the data in Redis
    const databaseData = await fetchDataFromDatabase(key);
    await client.set(key, databaseData);

    // Return the data fetched from the database
    res.json({ key, databaseData });
  }
});

app.listen(port, () =&amp;gt; {
  console.log(`Now listening on port ${port}`);
});


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

&lt;/div&gt;






&lt;p&gt;Stay tuned for our next section, where we'll dive deeper into this practical scenario and demonstrate how to seamlessly integrate Redis caching with your database interactions. If you haven't already, make sure Redis is running, and your Express server is up and listening on port 880. Happy coding!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>redis</category>
      <category>node</category>
      <category>caching</category>
    </item>
    <item>
      <title>Setting Up Redis and Express for Your Application</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Fri, 17 Nov 2023 03:02:33 +0000</pubDate>
      <link>https://dev.to/techjayvee/setting-up-redis-and-express-for-your-application-2e22</link>
      <guid>https://dev.to/techjayvee/setting-up-redis-and-express-for-your-application-2e22</guid>
      <description>&lt;h2&gt;
  
  
  Setting Up Redis and Express for Your Application
&lt;/h2&gt;

&lt;p&gt;Welcome back! In the previous section, we explored the concept of Redis caching and how it can significantly boost query performance. Now, let's dive into the practical side of things and set up Redis on our local machine to get ready for integration with our Express.js application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Downloading Redis:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Visit Redis Official Page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the official &lt;a href="https://redis.io/download/"&gt;Redis page&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Choose Stable Version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the Downloads page, select the stable version for your operating system.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download and Extract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click "Download" to get the Redis archive.&lt;/li&gt;
&lt;li&gt;Extract the contents to a directory of your choice.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run Redis Server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the extracted folder.&lt;/li&gt;
&lt;li&gt;Enter the "src" directory.&lt;/li&gt;
&lt;li&gt;Find and execute the "redis-server" executable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test Connection with Redis CLI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open another terminal.&lt;/li&gt;
&lt;li&gt;Navigate to the same directory.&lt;/li&gt;
&lt;li&gt;Run the "&lt;code&gt;redis-cli&lt;/code&gt;" executable.&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;ping&lt;/code&gt; to test the connection. You should receive a "pong" response.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5NF8I9bR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kq3kcdloa3t66x22by0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5NF8I9bR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kq3kcdloa3t66x22by0r.png" alt="Image description" width="729" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it! You now have Redis up and running on your local machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting Up Your Express Application:
&lt;/h2&gt;

&lt;p&gt;Now, let's set up an Express.js application to integrate with Redis.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Initialize Node Application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open your preferred text editor (e.g., Visual Studio Code) in an empty directory.&lt;/li&gt;
&lt;li&gt;Open the integrated terminal.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npm init -y&lt;/code&gt; to initialize a Node.js application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Express:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create an &lt;code&gt;index.js&lt;/code&gt; file.&lt;br&gt;
Install Express using &lt;code&gt;npm install express&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// index.js
const express = require('express');
const app = express();

const port = 8800;

app.listen(port, () =&amp;gt; {
  console.log(`Now listening on port ${port}`);
});

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install Nodemon (Optional):

&lt;ul&gt;
&lt;li&gt;Install Nodemon globally for automatic server updates.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;npm install -g nodemon&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install Redis Library:

&lt;ul&gt;
&lt;li&gt;Install the redis library for connecting to Redis.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;npm install redis&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// index.js
const express = require('express');
const redis = require('redis');

const app = express();
const port = 880;

const redisUrl = 'redis://localhost:6379';
const client = redis.createClient(redisUrl);

app.use(express.json());

app.listen(port, () =&amp;gt; {
  console.log(`Now listening on port ${port}`);
});

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

&lt;/div&gt;






&lt;p&gt;With Redis and Express set up, we are ready to move on to the next section, where we'll explore how to insert data into Redis. Stay tuned for the continuation of this tutorial!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>redis</category>
      <category>node</category>
      <category>caching</category>
    </item>
    <item>
      <title>Understanding Caching with Redis: A Step-by-Step Tutorial</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Fri, 17 Nov 2023 03:02:01 +0000</pubDate>
      <link>https://dev.to/techjayvee/understanding-caching-with-redis-a-step-by-step-tutorial-111a</link>
      <guid>https://dev.to/techjayvee/understanding-caching-with-redis-a-step-by-step-tutorial-111a</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;Welcome back, everyone! In this tutorial blog post, we'll dive into the concept of caching and explore how Redis, an open-source in-memory data structure store, can significantly speed up query times from our server.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Redis?
&lt;/h2&gt;

&lt;p&gt;On the RedisToGo landing page, Redis is described as an in-memory data structure store primarily used as a database cache. But what does "in-memory" mean, and why would we want to use it? Let's break it down.&lt;/p&gt;




&lt;h2&gt;
  
  
  In-Memory Data Store:
&lt;/h2&gt;

&lt;p&gt;Traditional databases like PostgreSQL and MongoDB store data persistently on disk. In contrast, an in-memory data store keeps data in volatile memory. If the system running the database goes down, the data is lost. So, why use in-memory databases?&lt;/p&gt;




&lt;h2&gt;
  
  
  Caching and Query Optimization:
&lt;/h2&gt;

&lt;p&gt;The primary reason is caching. Imagine a scenario where our server needs to retrieve a specific post from a database with millions or billions of records. Without optimization, the database would perform a full-body scan, searching through each record until it finds the requested one. This process can be slow and resource-intensive.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Redis as a Solution:
&lt;/h2&gt;

&lt;p&gt;To address this, we introduce Redis, an in-memory key-value store. Unlike traditional databases, Redis can immediately retrieve data associated with a specific key, offering a significant performance boost.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Redis Caching Works:
&lt;/h2&gt;

&lt;p&gt;We visualize the process with a server-database model. Traditionally, the server queries the database for data. With Redis, before going to the database, the server checks with Redis if it already has the required data. If Redis has the data (cached), the server retrieves it from Redis, skipping the potentially expensive database query.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Scenario:
&lt;/h2&gt;

&lt;p&gt;Consider a scenario where our application frequently requests post data with an ID. Redis allows us to cache this data, reducing the need for repeated, time-consuming database queries.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementing Redis Caching:
&lt;/h2&gt;

&lt;p&gt;In the next sections, we'll delve into a real-world example using Node.js as our server. However, note that Redis is versatile and works with various servers and languages. We'll cover the code implementation and explore how to leverage Redis to optimize query performance.&lt;/p&gt;




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

&lt;p&gt;Caching with Redis is a powerful technique for enhancing the speed and efficiency of data retrieval in applications with high query volumes. Stay tuned for the upcoming sections where we'll practically implement Redis caching in a Node.js environment.&lt;/p&gt;

&lt;p&gt;Stay connected for the next section, where we'll guide you through downloading Redis on your local machine. Redis is a valuable tool in your development arsenal, regardless of the server or language you're working with. See you in the next section!&lt;/p&gt;

</description>
      <category>node</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>redis</category>
    </item>
    <item>
      <title>Dynamic rate-limiting middleware in Express</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Tue, 14 Nov 2023 02:39:26 +0000</pubDate>
      <link>https://dev.to/techjayvee/dynamic-rate-limiting-middleware-in-express-5hlm</link>
      <guid>https://dev.to/techjayvee/dynamic-rate-limiting-middleware-in-express-5hlm</guid>
      <description>&lt;p&gt;To create a dynamic rate-limiting middleware in Express that can be used at different levels (controller, app, router), you can use the &lt;code&gt;express-rate-limit&lt;/code&gt; package. This middleware can be configured dynamically based on the parameters you pass.&lt;/p&gt;

&lt;p&gt;Here's an example of a custom rate-limiting middleware that can be used at different levels in Express:&lt;/p&gt;

&lt;p&gt;First, install the &lt;code&gt;express-rate-limit&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install express-rate-limit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create a module that exports a function to generate the rate-limiting middleware dynamically:&lt;br&gt;
&lt;/p&gt;

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

const rateLimit = require("express-rate-limit");

function createRateLimitMiddleware(options) {
  // You can configure the rate limit dynamically using the options parameter
  const limiter = rateLimit({
    windowMs: options.windowMs || 60 * 1000, // 1 minute by default
    max: options.max || 100, // 100 requests per windowMs by default
    message: options.message || "Too many requests, please try again later."
  });

  return limiter;
}

module.exports = createRateLimitMiddleware;

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

&lt;/div&gt;






&lt;p&gt;Next, in your Express application, you can use this dynamically created rate-limiting middleware in different levels:&lt;/p&gt;

&lt;h2&gt;
  
  
  At the App Level:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express");
const app = express();
const createRateLimitMiddleware = require("./rateLimitMiddleware");

// Apply rate limiting for the entire app
const appLevelRateLimiter = createRateLimitMiddleware({
  windowMs: 60 * 60 * 1000, // 1 hour
  max: 1000, // 1000 requests per hour
});

app.use(appLevelRateLimiter);
// Other app configurations and routes

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  At the Router/Route Level:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express");
const router = express.Router();
const createRateLimitMiddleware = require("./rateLimitMiddleware");

// Apply rate limiting for a specific router
const routerLevelRateLimiter = createRateLimitMiddleware({
  windowMs: 60 * 1000, // 1 minute
  max: 30, // 30 requests per minute
});

router.use(routerLevelRateLimiter);
// Define router paths and their respective handlers

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  At the Controller Level (per route):
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express");
const router = express.Router();
const createRateLimitMiddleware = require("./rateLimitMiddleware");

// Apply rate limiting for specific routes/controllers
const specificRouteRateLimiter = createRateLimitMiddleware({
  windowMs: 60 * 1000, // 1 minute
  max: 10, // 10 requests per minute
});

router.get("/specific-route", specificRouteRateLimiter, (req, res) =&amp;gt; {
  // Controller logic for the specific route
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup allows you to dynamically configure rate-limiting based on your specific needs at different levels within your Express application. Adjust the parameters in the options object passed to createRateLimitMiddleware to fit your requirements.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>express</category>
      <category>expressratelimit</category>
    </item>
    <item>
      <title>13.1 Payment Integration</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Tue, 07 Nov 2023 03:28:42 +0000</pubDate>
      <link>https://dev.to/techjayvee/131-payment-integration-2542</link>
      <guid>https://dev.to/techjayvee/131-payment-integration-2542</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we will continue our journey of building a microservice-based reservation system with payment integration using NestJS. We've previously covered setting up the communication between the reservation and payment services. In this post, we will focus on billing the user and implementing validation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Billing the User
&lt;/h2&gt;

&lt;p&gt;Before we create a reservation in our database, we want to bill the user using the newly created CreateChargeDTO and our payments service.&lt;br&gt;
update your &lt;code&gt;reservations.service.ts&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

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

import { ReservationsRepository } from './reservations.repository';
import { CreateReservationDto } from './dto/create-reservation.dto';
import { UpdateReservationDto } from './dto/update-reservation.dto';
import { PAYMENTS_SERVICE } from '@app/common';
import { ClientProxy } from '@nestjs/microservices';
import { map } from 'rxjs';

@Injectable()
export class ReservationsService {
  constructor(
    private readonly reservationsRepository: ReservationsRepository,
    @Inject(PAYMENTS_SERVICE) private readonly payment_service: ClientProxy,
  ) {}

  async create(createReservationDto: CreateReservationDto, userId: string) {
    return this.payment_service
      .send('create_charge', createReservationDto.charge)
      .pipe(
        map(async () =&amp;gt; {
          return this.reservationsRepository.create({
            ...createReservationDto,
            timestamp: new Date(),
            userId,
          });
        }),
      );
  }

  async findAll() {
    return this.reservationsRepository.find({});
  }

  async findOne(_id: string) {
    return this.reservationsRepository.findOne({ _id });
  }

  async update(_id: string, updateReservationDto: UpdateReservationDto) {
    return this.reservationsRepository.findOneAndUpdate(
      { _id },
      { $set: updateReservationDto },
    );
  }

  async remove(_id: string) {
    return this.reservationsRepository.findOneAndDelete({ _id });
  }
}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Dynamic Invoice IDs
&lt;/h2&gt;

&lt;p&gt;Instead of hardcoding the invoice ID, let's extract it from the Stripe response, to ensure that it correlates the reservation with the Stripe charge. This dynamic approach ensures accurate invoice tracking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update the Create Reservation DTO: (&lt;code&gt;create-reservation.dto.ts&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { CreateChargeDto } from '@app/common';
import { Type } from 'class-transformer';
import { IsDate, IsDefined, IsNotEmpty, ValidateNested } from 'class-validator';

export class CreateReservationDto {
  @IsDate()
  @Type(() =&amp;gt; Date)
  startDate: Date;

  @IsDate()
  @Type(() =&amp;gt; Date)
  endDate: Date;

  @Type(() =&amp;gt; CreateChargeDto)
  @IsDefined()
  @IsNotEmpty()
  @ValidateNested()
  charge: CreateChargeDto;
}

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We removed the user-supplied invoice ID field and&lt;br&gt;
eliminate unused fields place ID.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Update the Reservation Schema:(&lt;code&gt;reservation.entity.ts&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { AbstractDocument } from '@app/common';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';

@Schema({ versionKey: false })
export class ReservationDocument extends AbstractDocument {
  @Prop({ type: Date, default: Date.now })
  timestamp: Date;

  @Prop({ type: Date, required: true })
  startDate: Date;

  @Prop({ type: Date, required: true })
  endDate: Date;

  @Prop({ type: String, required: true })
  userId: string;

  @Prop({ type: String, required: true })
  invoiceId: string;
}

export const ReservationSchema =
  SchemaFactory.createForClass(ReservationDocument);

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We removed the place ID field since it is not being used and retained the invoice ID field to store the dynamically extracted ID.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Update your &lt;code&gt;reservations.service.ts&lt;/code&gt; with the following content:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

import { ReservationsRepository } from './reservations.repository';
import { CreateReservationDto } from './dto/create-reservation.dto';
import { UpdateReservationDto } from './dto/update-reservation.dto';
import { PAYMENTS_SERVICE } from '@app/common';
import { ClientProxy } from '@nestjs/microservices';
import { map } from 'rxjs';

@Injectable()
export class ReservationsService {
  constructor(
    private readonly reservationsRepository: ReservationsRepository,
    @Inject(PAYMENTS_SERVICE) private readonly payment_service: ClientProxy,
  ) {}

  async create(createReservationDto: CreateReservationDto, userId: string) {
    return this.payment_service
      .send('create_charge', createReservationDto.charge)
      .pipe(
        map(async (res) =&amp;gt; {
          return this.reservationsRepository.create({
            ...createReservationDto,
            timestamp: new Date(),
            invoiceId: res.id,
            userId,
          });
        }),
      );
  }

  async findAll() {
    return this.reservationsRepository.find({});
  }

  async findOne(_id: string) {
    return this.reservationsRepository.findOne({ _id });
  }

  async update(_id: string, updateReservationDto: UpdateReservationDto) {
    return this.reservationsRepository.findOneAndUpdate(
      { _id },
      { $set: updateReservationDto },
    );
  }

  async remove(_id: string) {
    return this.reservationsRepository.findOneAndDelete({ _id });
  }
}

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;When creating a reservation, we send a request to Stripe to create a payment intent.&lt;/li&gt;
&lt;li&gt;In the response from Stripe, we extract the payment intent ID, which serves as the invoice ID.&lt;/li&gt;
&lt;li&gt;We use this extracted invoice ID to correlate the reservation with the Stripe charge.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;In this tutorial, we've extended our microservice-based reservation system with payment integration, focusing on billing the user and implementing robust validation. We've also shown how to handle unauthorized requests and dynamically extract invoice IDs for precise tracking. Furthermore, by using default test cards, we ensure secure payment processing. This comprehensive guide will help you build a robust and secure reservation system with payment capabilities using NestJS. Happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>13. Integrating and Validating Payment Services in a Reservation System</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Tue, 07 Nov 2023 03:28:27 +0000</pubDate>
      <link>https://dev.to/techjayvee/13-integrating-and-validating-payment-services-in-a-reservation-system-f8l</link>
      <guid>https://dev.to/techjayvee/13-integrating-and-validating-payment-services-in-a-reservation-system-f8l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we will walk you through the process of integrating a payment service with a reservation service. This integration will enable your application to bill users for reservations. We will also cover the validation of input data to ensure data consistency and security. &lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Define Payment Service
&lt;/h2&gt;

&lt;p&gt;Define &lt;code&gt;PAYMENTS_SERVICE&lt;/code&gt;  in your &lt;strong&gt;libs/common/src/constants/service.ts&lt;/strong&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const AUTH_SERVICE = 'auth';
export const PAYMENTS_SERVICE = 'payments';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Modify Reservation Module
&lt;/h2&gt;

&lt;p&gt;To enable the reservation service to communicate with the payment service, we first need to set up the payment service as a client. In your &lt;code&gt;reservations module&lt;/code&gt;, inject the payment service using an injection token:&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 { ReservationsService } from './reservations.service';
import { ReservationsController } from './reservations.controller';
import {
  AUTH_SERVICE,
  DatabaseModule,
  LoggerModule,
  PAYMENTS_SERVICE,
} from '@app/common';
import { ReservationsRepository } from './reservations.repository';
import {
  ReservationDocument,
  ReservationSchema,
} from './entities/reservation.entity';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as Joi from 'joi';
import { ClientsModule, Transport } from '@nestjs/microservices';

@Module({
  imports: [
    DatabaseModule,
    DatabaseModule.forFeature([
      { name: ReservationDocument.name, schema: ReservationSchema },
    ]),
    LoggerModule,
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: Joi.object({
        MONGODB_URI: Joi.string().required(),
        PORT: Joi.number().required(),
        AUTH_HOST: Joi.string().required(),
        AUTH_PORT: Joi.number().required(),
      }),
    }),
    ClientsModule.registerAsync([
      {
        name: AUTH_SERVICE,
        useFactory: (configService: ConfigService) =&amp;gt; ({
          transport: Transport.TCP,
          options: {
            host: configService.get('AUTH_HOST'),
            port: configService.get('AUTH_PORT'),
          },
        }),
        inject: [ConfigService],
      },
      {
        name: PAYMENTS_SERVICE,
        useFactory: (configService: ConfigService) =&amp;gt; ({
          transport: Transport.TCP,
          options: {
            host: configService.get('PAYMENTS_HOST'),
            port: configService.get('PAYMENTS_PORT'),
          },
        }),
        inject: [ConfigService],
      },
    ]),
  ],
  controllers: [ReservationsController],
  providers: [ReservationsService, ReservationsRepository],
})
export class ReservationsModule {}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Configure Environment Variables
&lt;/h2&gt;

&lt;p&gt;Since we are using two new environment variables, &lt;code&gt;PAYMENTS_HOST&lt;/code&gt; and &lt;code&gt;PAYMENTS_PORT&lt;/code&gt;, which do not yet exist in our .env file, let's go ahead and define them. Please open your payments .env file and modify its content with the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MONGODB_URI=mongodb://mongo:27017/reservation
PORT=3000
AUTH_HOST=auth
AUTH_PORT=3002
PAYMENTS_HOST=payments
PAYMENTS_PORT=3003
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Inject the Payment Service
&lt;/h2&gt;

&lt;p&gt;Inject the payment service using NestJS's @Inject decorator and call it as a client proxy for microservices. Ensure that the import statement is correct. &lt;br&gt;
update your &lt;code&gt;reservations.service.ts&lt;/code&gt; with this content:&lt;br&gt;
&lt;/p&gt;

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

import { ReservationsRepository } from './reservations.repository';
import { CreateReservationDto } from './dto/create-reservation.dto';
import { UpdateReservationDto } from './dto/update-reservation.dto';
import { PAYMENTS_SERVICE } from '@app/common';
import { ClientProxy } from '@nestjs/microservices';

@Injectable()
export class ReservationsService {
  @Inject(PAYMENTS_SERVICE) payment_service: ClientProxy;
  constructor(
    private readonly reservationsRepository: ReservationsRepository,
  ) {}

  async create(createReservationDto: CreateReservationDto, userId: string) {
    return this.reservationsRepository.create({
      ...createReservationDto,
      timestamp: new Date(),
      userId,
    });
  }

  async findAll() {
    return this.reservationsRepository.find({});
  }

  async findOne(_id: string) {
    return this.reservationsRepository.findOne({ _id });
  }

  async update(_id: string, updateReservationDto: UpdateReservationDto) {
    return this.reservationsRepository.findOneAndUpdate(
      { _id },
      { $set: updateReservationDto },
    );
  }

  async remove(_id: string) {
    return this.reservationsRepository.findOneAndDelete({ _id });
  }
}

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

&lt;/div&gt;



&lt;p&gt;This step allows you to use the payment service for billing users when creating reservations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Creating Card DTO
&lt;/h2&gt;

&lt;p&gt;Create a separate CardDTO to validate the credit card details. We will do it inside our &lt;strong&gt;libs/common/src/dto&lt;/strong&gt; folder to allow us to use the &lt;strong&gt;CardDTO&lt;/strong&gt; anywhere in our apps to avoid duplication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch libs/common/src/dto/card.dto.ts
touch libs/common/src/dto/create-charge.dto.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;populate your &lt;code&gt;card.dto.ts&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { IsCreditCard, IsNotEmpty, IsNumber, IsString } from 'class-validator';

export class CardDTO {
  @IsString()
  @IsNotEmpty()
  cvc: string;

  @IsNumber()
  exp_month: number;

  @IsNumber()
  exp_year: number;

  @IsCreditCard()
  number: string;
}

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

&lt;/div&gt;



&lt;p&gt;populate your &lt;code&gt;create-charge.dto.ts&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { CardDTO } from './card.dto';
import { Type } from 'class-transformer';
import {
  IsDefined,
  IsNotEmpty,
  ValidateNested,
  IsNumber,
} from 'class-validator';

export class CreateChargeDto {
  @Type(() =&amp;gt; CardDTO)
  @IsDefined()
  @IsNotEmpty()
  @ValidateNested()
  card: CardDTO;

  @IsNumber()
  amount: number;
}


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

&lt;/div&gt;



&lt;p&gt;Make sure to update the &lt;strong&gt;libs/common/src/dto/index.ts&lt;/strong&gt; and export the newly created &lt;strong&gt;CardDTO&lt;/strong&gt; and &lt;strong&gt;CreateChargeDto&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export * from './user.dto';
export * from './card.dto';
export * from './create-charge.dto';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Please remember that we have already created a 'create-charge.dto' in our payments app. We need to delete the existing one and replace it with the newly created 'create-charge.dto' located inside our common folder. This change is necessary because we have not applied any validation to the 'create-charge.dto' in our payments app.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;update your &lt;code&gt;paymens.controller.ts&lt;/code&gt; with the following content to use our newly created &lt;strong&gt;create-charge.dto.ts&lt;/strong&gt; in our @app/common:&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 { PaymentsService } from './payments.service';
import { MessagePattern, Payload } from '@nestjs/microservices';
import { CreateChargeDto } from '@app/common';

@Controller()
export class PaymentsController {
  constructor(private readonly paymentsService: PaymentsService) {}

  @MessagePattern('create_charge')
  async createcharge(@Payload() data: CreateChargeDto) {
    return this.paymentsService.createCharge(data);
  }
}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 6: Updating the Create Reservation DTO
&lt;/h2&gt;

&lt;p&gt;To facilitate billing for reservations, update the Create Reservation DTO to include a card property.&lt;/p&gt;

&lt;p&gt;In your reservation app inside the dto folder, Open your &lt;code&gt;create-reservation.dto.ts&lt;/code&gt; file and update with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { CardDTO } from '@app/common';
import { Type } from 'class-transformer';
import {
  IsDate,
  IsDefined,
  IsNotEmpty,
  IsNumber,
  IsString,
  ValidateNested,
} from 'class-validator';

export class CreateReservationDto {
  @IsDate()
  @Type(() =&amp;gt; Date)
  startDate: Date;

  @IsDate()
  @Type(() =&amp;gt; Date)
  endDate: Date;

  @IsString()
  @IsNotEmpty()
  placeId: string;

  @IsString()
  @IsNotEmpty()
  invoiceId: string;

  @Type(() =&amp;gt; CardDTO)
  @IsDefined()
  @IsNotEmpty()
  @ValidateNested()
  card: CardDTO;

  @IsNumber()
  amount: number;
}

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

&lt;/div&gt;






&lt;p&gt;Step 7: Test Your DTO&lt;/p&gt;

&lt;p&gt;Test Scenario: Reservation Creation with Validation&lt;br&gt;
Request Details:&lt;/p&gt;

&lt;p&gt;Method: POST&lt;br&gt;
Endpoint: &lt;a href="http://localhost:3000/reservations"&gt;http://localhost:3000/reservations&lt;/a&gt;&lt;br&gt;
Test Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Invalid Card Information missing &lt;code&gt;cvc&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Send a POST request with the following payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "startDate": "2023-11-01",
  "endDate": "2023-11-05",
  "placeId": "1232",
  "invoiceId": "67890",
  "charge": {
   "card": {
    "exp_month": 12,     
    "exp_year": 2025,      
    "number": "4242 4242 4242 4242"  
  },
  "amount": 99.99
  }
}

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

&lt;/div&gt;



&lt;p&gt;Check the response for validation errors, especially for the "cvc" field.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Valid Card Information&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Send a POST request with the following payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "startDate": "2023-11-01",
  "endDate": "2023-11-05",
  "placeId": "1232",
  "invoiceId": "67890",
  "charge": {
   "card": {
    "cvc": "123",
    "exp_month": 12,     
    "exp_year": 2025,      
    "number": "4242 4242 4242 4242"  
  },
  "amount": 99.99
  }
}

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

&lt;/div&gt;



&lt;p&gt;Check the response for a successful reservation creation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expected Outcomes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Step 1, you should receive a validation error response indicating that the "cvc" field is incorrect.&lt;/p&gt;

&lt;p&gt;In Step 2, you should receive a successful reservation creation response.&lt;/p&gt;

&lt;p&gt;This scenario will help you verify if the validation is working correctly and if the reservation creation is functioning as expected.&lt;/p&gt;




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

&lt;p&gt;You've successfully integrated and validated the payment service in your reservation system. With robust schema validation and proper data exchange, you can ensure a reliable and secure booking process. This tutorial provides a foundation for building more complex systems and enhancing the capabilities of your microservices. Happy coding!&lt;/p&gt;

&lt;p&gt;In the next lesson, we will connect it with our Stripe to persist our payments and make a few modifications to our payment service. This will be our last lesson in payment integration.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>12. Payment Processing with Stripe API</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Tue, 07 Nov 2023 03:28:11 +0000</pubDate>
      <link>https://dev.to/techjayvee/12-payment-processing-with-stripe-api-3e32</link>
      <guid>https://dev.to/techjayvee/12-payment-processing-with-stripe-api-3e32</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today's tutorial, we will guide you through creating a microservice for processing payments in your reservation system using the Stripe API. This microservice will handle the task of billing customers when they book reservations, and we'll take you through each step to set it up.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Creating a New NestJS App
&lt;/h2&gt;

&lt;p&gt;To kick things off, we'll use the Nest CLI to generate a new app. Open your terminal and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nest generate app payments

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

&lt;/div&gt;



&lt;p&gt;This command creates a new NestJS application named "payments" for handling payments in your reservation system. It includes a default controller and a basic payments module.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Docker Configuration
&lt;/h2&gt;

&lt;p&gt;Next, we'll set up Docker for this microservice. I will not explain this code because we already tackled it in our previous tutorials&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch apps/payments/Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it will create a &lt;strong&gt;Dockerfile&lt;/strong&gt; inside the &lt;code&gt;payments&lt;/code&gt; folder now populate it with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Use Node Alpine as the base image for development
FROM node:alpine as development

WORKDIR /usr/src/app

COPY package.json package-lock.json ./
RUN npm install -g &amp;amp;&amp;amp; npm install

COPY . .

RUN npm run build

# Create a production image
FROM node:alpine as production

ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

WORKDIR /usr/src/app

COPY package.json package-lock.json ./
RUN npm install --only=production

COPY --from=development /usr/src/app/dist ./dist
COPY --from=development /usr/src/app/package.json ./package.json

CMD [ "node", "dist/apps/payments/main" ]

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

&lt;/div&gt;



&lt;p&gt;What we did was just Copy the Docker file from your reservations app and place it in the payments app folder. In the Docker file, we changed the startup command to point to the dist/apps/payments folder.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Update docker-compose.yaml&lt;/strong&gt; - Now, update your Docker Compose file to include the payments service. Make sure to specify a unique port (e.g., 3003) and expose it for the payments microservice.&lt;/p&gt;

&lt;p&gt;Open your docker-compose file and update it with the following content to include payment service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  reservations:
    build:
      context: .
      dockerfile: apps/reservations/Dockerfile
      target: development
    command: npm run start:dev reservations
    env_file:
      - ./apps/reservations/.env
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/app
  auth:
    build:
      context: .
      dockerfile: apps/auth/Dockerfile
      target: development
    command: npm run start:dev auth
    env_file:
      - apps/auth/.env
    ports:
      - '3001:3001'
    volumes:
      - .:/usr/src/app
  payments:
    build:
      context: .
      dockerfile: apps/payments/Dockerfile
      target: development
    command: npm run start:dev payments
    env_file:
      - apps/payments/.env
    ports:
      - '3003:3003'
    volumes:
      - .:/usr/src/app
  mongo:
    image: mongo

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Configuring the Microservice
&lt;/h2&gt;

&lt;p&gt;In the payments folder, open the &lt;strong&gt;main.ts&lt;/strong&gt; file and turn this app into a standalone microservice. Update it with the following content:&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 { PaymentsModule } from './payments.module';
import { Logger } from 'nestjs-pino';
import { Transport } from '@nestjs/microservices';
import { ConfigService } from '@nestjs/config';

async function bootstrap() {
  const app = await NestFactory.create(PaymentsModule);
  const configService = app.get(ConfigService);
  app.connectMicroservice({
    transport: Transport.TCP,
    options: {
      host: '0.0.0.0',
      port: configService.get('PORT'),
    },
  });

  app.useLogger(app.get(Logger));

  await app.startAllMicroservices();
}
bootstrap();


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

&lt;/div&gt;



&lt;p&gt;We just configure the transport as "transport.TCP" and set the port using the config service. But since we are using a &lt;strong&gt;PORT&lt;/strong&gt; environment variable which does not yet exist in the payments service we should now create a .env file and specify the PORT variables&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch apps/payments/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;populate it with the following code:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then on your config module in the payments module (&lt;code&gt;payments.module.ts&lt;/code&gt;) set it up as we did for the auth service. This allows you to access and validate the &lt;strong&gt;PORT&lt;/strong&gt; environment variable as follows:&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 { PaymentsController } from './payments.controller';
import { PaymentsService } from './payments.service';
import * as Joi from 'joi';
import { ConfigModule } from '@nestjs/config';
import { LoggerModule } from '@app/common';

@Module({
  imports: [
    LoggerModule,
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: Joi.object({
        PORT: Joi.number().required(),
        STRIPE_SECRET_KEY: Joi.string().required(), //we will set up this on step 4
      }),
    }),
  ],
  controllers: [PaymentsController],
  providers: [PaymentsService],
})
export class PaymentsModule {}


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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Setting up the Stripe API
&lt;/h2&gt;

&lt;p&gt;Before you can start processing payments, you need to set up a Stripe account. Head to &lt;a href="https://stripe.com/"&gt;Stripe's website&lt;/a&gt;, sign up for an account, and create an account within your dashboard.&lt;/p&gt;

&lt;p&gt;In your Stripe dashboard, you will find your &lt;code&gt;publishable key&lt;/code&gt; and &lt;code&gt;secret key&lt;/code&gt;. We will use the &lt;code&gt;secret key&lt;/code&gt; for API calls, so make sure to set it as an environment variable in your .env file.&lt;/p&gt;

&lt;p&gt;update your &lt;code&gt;payments .env&lt;/code&gt; file and include your &lt;strong&gt;secret_key&lt;/strong&gt; which you got from your stripe dashboard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PORT=3003
STRIPE_SECRET_KEY=sk_test_51NZp96JyPkGHZlunZYLEUwARyNBuxHbJ3tVFat6XtJxSxLwhJgIxMdeC4wtt42WkrWCM3H20yRVeMkc9SW38Uprt00xPMCJIDR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Make sure to use your own secret key, the secret key I provided is deactivated&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, install the Node.js Stripe API client library with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install stripe

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Initializing the Stripe Client
&lt;/h2&gt;

&lt;p&gt;let's create a DTO (Data Transfer Object) first&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir apps/payments/src/dto
touch apps/payments/src/dto/create-charge.dto.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it will create a new directory named &lt;code&gt;dto&lt;/code&gt; inside your payments folder then inside &lt;code&gt;dto&lt;/code&gt; it will create a file named &lt;code&gt;create-charge.dto.ts&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;populate the &lt;strong&gt;create-charge.dto.ts&lt;/strong&gt; with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Stripe from 'stripe';

export class CreateChargeDto {
  card: Stripe.PaymentMethodCreateParams.Card1;
  amount: number;
}

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We can now use this CreatechargeDto to our controller and service&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Open your &lt;code&gt;payments.service.ts&lt;/code&gt; and populate it with the following content:&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 { ConfigService } from '@nestjs/config';
import Stripe from 'stripe';
import { CreateChargeDto } from './dto/create-charge.dto';

@Injectable()
export class PaymentsService {
  private readonly stripe = new Stripe(
    this.configService.get('STRIPE_SECRET_KEY'),
    {
      apiVersion: '2023-10-16',
    },
  );
  constructor(private readonly configService: ConfigService) {}

  async createCharge({ amount }: CreateChargeDto) {
    const paymentIntent = await this.stripe.paymentIntents.create({
      amount: amount * 100,
      automatic_payment_methods: {
        enabled: true,
        allow_redirects: 'never',
      },
      confirm: true,
      payment_method: 'pm_card_visa',
      currency: 'usd',
    });

    return paymentIntent;
  }
}

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

&lt;/div&gt;



&lt;p&gt;In the payments service, we created a private read-only variable to initialize the Stripe client using your secret key from the config service. and we set up the API version as well.&lt;/p&gt;

&lt;p&gt;We also create a payment charge. using the Payment Intents API provided by Stripe for secure payment processing. We created a new payment method and then charged the user.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We created a payment intent with the payment method and charge amount.&lt;/li&gt;
&lt;li&gt;We set the confirm the payment intent to true to charge the user immediately.&lt;/li&gt;
&lt;li&gt;We add an async method called** createCharge** to handle payment charges. Define the parameters, such as the card details and the amount to charge.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 7: Exposing the Payment Service
&lt;/h2&gt;

&lt;p&gt;To make the payment service accessible to other microservices, set up a new async route in the &lt;strong&gt;payments controller&lt;/strong&gt; decorated with the &lt;strong&gt;@MessagePattern&lt;/strong&gt; decorator. Extract the payload and define a dedicated DTO for the data being passed to the create charge method.&lt;/p&gt;

&lt;p&gt;Open your &lt;strong&gt;payment.controller.ts&lt;/strong&gt; then update its content with this code:&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, UsePipes, ValidationPipe } from '@nestjs/common';
import { PaymentsService } from './payments.service';
import { MessagePattern, Payload } from '@nestjs/microservices';
import { CreateChargeDto } from '@app/common';

@Controller()
export class PaymentsController {
  constructor(private readonly paymentsService: PaymentsService) {}

  @MessagePattern('create_charge')
  @UsePipes(new ValidationPipe())
  async createcharge(@Payload() data: CreateChargeDto) {
    return this.paymentsService.createCharge(data);
  }
}

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

&lt;/div&gt;



&lt;p&gt;We use NestJS's built-in &lt;code&gt;validation pipes&lt;/code&gt; to validate the incoming metadata on the payload.&lt;/p&gt;




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

&lt;p&gt;Congratulations! You've successfully created a microservice for processing payments using the Stripe API. This service can be integrated into your reservation system to handle payment processing securely. With the right configuration and integration, your application is ready to bill customers for their reservations.&lt;/p&gt;

&lt;p&gt;In the next lessons, we will integrate and test it with our reservations.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>11. Implementing Authentication in Microservices with NestJS</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Tue, 07 Nov 2023 03:27:58 +0000</pubDate>
      <link>https://dev.to/techjayvee/11-implementing-authentication-in-microservices-with-nestjs-2jah</link>
      <guid>https://dev.to/techjayvee/11-implementing-authentication-in-microservices-with-nestjs-2jah</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;In a microservices architecture, securing your services and routes is of paramount importance. One way to achieve this is by implementing authentication. This blog post will guide you through the process of adding JWT-based authentication to your routes in a NestJS-based microservices setup. We'll create a common JWT authentication guard that can be reused across various microservices to protect routes, ensuring that only authenticated users can access them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;p&gt;Before getting started, make sure you have the following prerequisites in place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A basic understanding of NestJS and microservices.&lt;/li&gt;
&lt;li&gt;NestJS installed.&lt;/li&gt;
&lt;li&gt;Docker and Docker Compose for containerization.&lt;/li&gt;
&lt;li&gt;Postman (or any other API testing tool) for testing your routes.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 1: Setting up Microservices with NestJS
&lt;/h2&gt;

&lt;p&gt;To enable communication between microservices, you'll need to set up a transport layer. We'll use a TCP-based transport layer for this tutorial. Start by installing the necessary NestJS microservices package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @nestjs/microservices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Once installed, make sure to update the content of your &lt;strong&gt;apps/auth/src/main.ts&lt;/strong&gt; file in your authentication service with the following content:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NestFactory } from '@nestjs/core';
import { AuthModule } from './auth.module';
import { ValidationPipe } from '@nestjs/common';
import { Logger } from 'nestjs-pino';
import { ConfigService } from '@nestjs/config';
import * as cookieParser from 'cookie-parser';
import { Transport } from '@nestjs/microservices';

async function bootstrap() {
  const app = await NestFactory.create(AuthModule);
  const configService = app.get(ConfigService);
  app.connectMicroservice({
    transport: Transport.TCP,
    options: {
      host: '0.0.0.0',
      port: configService.get('TCP_PORT'),
    },
  });
  app.use(cookieParser());
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
    }),
  );
  app.useLogger(app.get(Logger));

  await app.startAllMicroservices();
  await app.listen(configService.get('HTTP_PORT'));
}
bootstrap();

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

&lt;/div&gt;



&lt;p&gt;Our host property  &lt;strong&gt;0.0.0.0&lt;/strong&gt;, which tells the microservice to bind to all interfaces on the host, and then for the port, I extract this from the environment. &lt;br&gt;
we call this environment variable &lt;strong&gt;TCP_PORT&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I also changed the &lt;strong&gt;PORT&lt;/strong&gt; variable for our HTTP server and called this &lt;strong&gt;HTTP_PORT&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This configuration allows your authentication service to communicate with other services via TCP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;since we are using a new environment variable and renaming the old variable &lt;code&gt;PORT&lt;/code&gt; to &lt;code&gt;HTTP_PORT&lt;/code&gt; which is not yet declared in our &lt;code&gt;auth .env&lt;/code&gt; file let's update our .env file and add the  &lt;strong&gt;HTTP_PORT&lt;/strong&gt; and &lt;strong&gt;TCP_PORT&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JWT_SECRET=your_secret_key
JWT_EXPIRATION=3600
HTTP_PORT=3001
TCP_PORT=3002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember that we validated all our environment variables in our auth module so we need also to update our auth.module.ts with the following content:&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 { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UsersModule } from './users/users.module';
import { LoggerModule } from '@app/common';
import { JwtModule } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as Joi from 'joi';
import { LocalStrategy } from './strategies/local.strategy';
import { JwtStrategy } from './strategies/jwt.strategy';

@Module({
  imports: [
    UsersModule,
    LoggerModule,
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: Joi.object({
        JWT_SECRET: Joi.string().required(),
        JWT_EXPIRATION: Joi.string().required(),
        HTTP_PORT: Joi.number().required(),
        TCP_PORT: Joi.number().required(),
      }),
    }),
    JwtModule.registerAsync({
      useFactory: (configService: ConfigService) =&amp;gt; ({
        secret: configService.get&amp;lt;string&amp;gt;('JWT_SECRET'),
        signOptions: {
          expiresIn: `${configService.get&amp;lt;string&amp;gt;('JWT_EXPIRATION')}s`,
        },
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [AuthController],
  providers: [AuthService, LocalStrategy, JwtStrategy],
})
export class AuthModule {}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Creating a Common JWT Auth Guard
&lt;/h2&gt;

&lt;p&gt;The next step is to create a common JWT authentication guard that can be used across different services. This guard will validate JWT tokens passed in requests. To do this, create a new folder in your common directory for auth-related components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir libs/common/src/auth
touch libs/common/src/auth/jwt-auth.guard.ts
touch libs/common/src/auth/index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it will create an &lt;code&gt;auth&lt;/code&gt; directory in your common library then inside that directory it will create two files the &lt;code&gt;index.ts&lt;/code&gt; and the &lt;code&gt;jwt-auth.guard.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;let's also create a &lt;strong&gt;constants&lt;/strong&gt; folder inside our common library in which all our services stored in constant variable will live:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir libs/common/src/constants
touch libs/common/src/constants/service.ts
touch libs/common/src/constants/index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;populate your &lt;strong&gt;constants/service.ts&lt;/strong&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const AUTH_SERVICE = 'auth';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also populate your &lt;strong&gt;constants/index.ts&lt;/strong&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export * from './service';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;since we created the necessary files and folders we need let's now populate our &lt;strong&gt;auth/jwt-auth.guard.ts&lt;/strong&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {
  CanActivate,
  ExecutionContext,
  Inject,
  Injectable,
} from '@nestjs/common';
import { Observable, of } from 'rxjs';
import { ClientProxy } from '@nestjs/microservices';
import { Request } from 'express';

import { catchError, map, tap } from 'rxjs/operators';
import { AUTH_SERVICE } from '../constants/service';

@Injectable()
export class JwtAuthGuard implements CanActivate {
  constructor(@Inject(AUTH_SERVICE) private readonly authClient: ClientProxy) {}

  canActivate(
    context: ExecutionContext,
  ): boolean | Promise&amp;lt;boolean&amp;gt; | Observable&amp;lt;boolean&amp;gt; {
    const jwt =
      context.switchToHttp().getRequest().cookies?.Authentication ||
      context.switchToHttp().getRequest()?.Authentication ||
      context.switchToHttp().getRequest().headers?.Authentication;
    console.log('jwt', jwt);

    if (!jwt) {
      return false;
    }

    return this.authClient
      .send('authenticate', {
        Authentication: jwt,
      })
      .pipe(
        tap((res) =&amp;gt; {
          context.switchToHttp().getRequest&amp;lt;Request&amp;gt;().user = res;
        }),
        map(() =&amp;gt; true),
        catchError(() =&amp;gt; of(false)),
      );
  }
}



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

&lt;/div&gt;



&lt;p&gt;This &lt;strong&gt;JwtAuthGuard&lt;/strong&gt; will check for the JWT token in the request's cookies. If a valid token is found, it communicates with the authentication service using the defined pattern and checks if the JWT is valid. If it's valid, it sets the user on the request object and allows the request to proceed.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;libs/common/src/auth/index.ts&lt;/strong&gt; file export your &lt;strong&gt;jwt-auth.guard.ts&lt;/strong&gt; by populating it with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//auth/index.ts
export * from './jwt-auth.guard';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;also in the &lt;strong&gt;libs/common/src/index.ts&lt;/strong&gt; file add export all from the auth folder and from constants folder by updating it with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export * from './database';
export * from './logger';
export * from './auth';
export * from './constants';

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Adding a Message Pattern for Authentication
&lt;/h2&gt;

&lt;p&gt;In your authentication service, set up a message pattern that corresponds to the authentication flow. In the &lt;strong&gt;apps/auth/src/auth.controller.ts&lt;/strong&gt; of your auth service, update your content with the following code:&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, Res, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalAuthGuard } from './guards/local.auth-guard';
import { CurrentUser } from './current-user.decorator';
import { UserDocument } from './users/models/user.schema';
import { Response } from 'express';
import { MessagePattern } from '@nestjs/microservices';
import { JwtAuthGuard } from './guards/jwt-auth.guard';

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

  @UseGuards(LocalAuthGuard)
  @Post('login')
  async login(
    @CurrentUser() user: UserDocument,
    @Res({ passthrough: true }) response: Response,
  ) {
    await this.authService.login(user, response);
    response.send(user);
  }

  @UseGuards(JwtAuthGuard)
  @MessagePattern('authenticate')
  async authenticate(@Payload() data: any) {
    return data.user;
  }
}

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

&lt;/div&gt;



&lt;p&gt;This code sets up a message pattern named &lt;code&gt;authenticate&lt;/code&gt; that can be used to authenticate JWT tokens we are using are existing JWTAUthGuard to do that. &lt;/p&gt;

&lt;p&gt;We also need to update our &lt;strong&gt;apps/auth/src/strategies/jwt.strategy.ts&lt;/strong&gt; because right now we are pulling the JWT off of the request header in the cookies object. However, when the JWT is coming in from our RPC call our JwtAuthGuard, it's not going to be inside of a cookies object.&lt;br&gt;
It's just going to be under the straight request object.&lt;/p&gt;

&lt;p&gt;So we can put in a bit of logic here to say if there is no request cookie, we can then check to see if the authentication key actually exists on the request object itself:&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 { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { UsersService } from '../users/users.service';
import { ConfigService } from '@nestjs/config';
import { Tokenpayload } from '../interface/token-payload.interface';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(
    configService: ConfigService,
    private readonly userService: UsersService,
  ) {
    super({
      jwtFromRequest: ExtractJwt.fromExtractors([
        (request: any) =&amp;gt;
          request?.cookies?.Authentication ||
          request?.Authentication ||
          request?.headers.Authentication,
      ]),
      secretOrKey: configService.get('JWT_SECRET'),
    });
  }

  async validate({ userId }: Tokenpayload) {
    return this.userService.getUser({ _id: userId });
  }
}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Registering the Authentication Service as a Client
&lt;/h2&gt;

&lt;p&gt;In the reservations service (or any other service that needs authentication), you need to register the authentication service as a client. Modify the reservations.module.ts file as follows:&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 { ReservationsService } from './reservations.service';
import { ReservationsController } from './reservations.controller';
import { AUTH_SERVICE, DatabaseModule, LoggerModule } from '@app/common';
import { ReservationsRepository } from './reservations.repository';
import {
  ReservationDocument,
  ReservationSchema,
} from './entities/reservation.entity';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as Joi from 'joi';
import { ClientsModule, Transport } from '@nestjs/microservices';

@Module({
  imports: [
    DatabaseModule,
    DatabaseModule.forFeature([
      { name: ReservationDocument.name, schema: ReservationSchema },
    ]),
    LoggerModule,
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: Joi.object({
        MONGODB_URI: Joi.string().required(),
        PORT: Joi.number().required(),
      }),
    }),
    ClientsModule.registerAsync([
      {
        name: AUTH_SERVICE,
        useFactory: (configService: ConfigService) =&amp;gt; ({
          transport: Transport.TCP,
          options: {
            host: configService.get('AUTH_HOST'),
            port: configService.get('AUTH_PORT'),
          },
        }),
        inject: [ConfigService],
      },
    ]),
  ],
  controllers: [ReservationsController],
  providers: [ReservationsService, ReservationsRepository],
})
export class ReservationsModule {}

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This code registers the authentication service as a client using the TCP transport layer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;since we are using two new environment variable which is not yet declared in our &lt;code&gt;reservations .env&lt;/code&gt; file let's update our .env file and add the  &lt;strong&gt;AUTH_HOST&lt;/strong&gt; and &lt;strong&gt;AUTH_PORT&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MONGODB_URI=mongodb://mongo:27017/reservation
PORT=3000
AUTH_HOST=auth
AUTH_PORT=3002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the &lt;code&gt;AUTH_HOST&lt;/code&gt; is actually defined in the &lt;code&gt;docker-compose.yaml&lt;/code&gt; services by the actual names of the services we defined.&lt;/p&gt;

&lt;p&gt;So the hostname for &lt;strong&gt;auth&lt;/strong&gt; will be &lt;strong&gt;auth&lt;/strong&gt; and the hostname for &lt;strong&gt;reservations&lt;/strong&gt; is &lt;strong&gt;reservations&lt;/strong&gt; running in Docker.&lt;br&gt;
So we set the auth host here to just be auth.&lt;br&gt;
And the &lt;strong&gt;AUTH_PORT&lt;/strong&gt; we set to 3002, which corresponds to the TCP_PORT we define in the auth service.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 5: User Extraction and DTO:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;user.dto.ts&lt;/strong&gt;&lt;br&gt;
We want to make the user object accessible across our application. For this, we'll define a &lt;strong&gt;Data Transfer Object (DTO)&lt;/strong&gt; for the user. This will ensure that the user data is consistent when sent over the network. Here's how you can create the user DTO:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir libs/common/src/dto
touch libs/common/src/dto/user.dto.ts
touch libs/common/src/dto/index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it will create a &lt;code&gt;dto&lt;/code&gt; directory in your common library and then inside that directory, it will create two files the &lt;code&gt;index.ts&lt;/code&gt; and the &lt;code&gt;user.dto.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;populate your &lt;code&gt;user.dto.ts&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface UserDTO {
  _id: string;
  email: string;
  password: string;
}

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

&lt;/div&gt;



&lt;p&gt;export your newly created UserDTO in your &lt;code&gt;index.ts&lt;/code&gt; by populating it with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export * from './user.dto';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;current-user.decorator.ts&lt;/strong&gt;&lt;br&gt;
To access the current user in your routes, you can create a decorators folder. Create a &lt;code&gt;current-user.decorator.ts&lt;/code&gt; file in the &lt;strong&gt;libs/common/src/decorators&lt;/strong&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir libs/common/src/decorators
touch libs/common/src/decorators/current-user.decorator.ts
touch libs/common/src/decorators/index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it will create a &lt;code&gt;decorators&lt;/code&gt; directory in your common library and then inside that directory, it will create two files the &lt;code&gt;index.ts&lt;/code&gt; and the &lt;code&gt;current-user.decorator.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;populate your &lt;strong&gt;current-user.decorator.ts&lt;/strong&gt; with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { UserDocument } from 'apps/auth/src/users/models/user.schema';

const getCurrentUserByContex = (ctx: ExecutionContext): UserDocument =&amp;gt; {
  return ctx.switchToHttp().getRequest().user;
};
export const CurrentUser = createParamDecorator(
  (_data: unknown, ctx: ExecutionContext) =&amp;gt; getCurrentUserByContex(ctx),
);

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

&lt;/div&gt;



&lt;p&gt;export your newly created CurrentUser  decorator in your &lt;code&gt;index.ts&lt;/code&gt; by populating it with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export * from './current-user.decorator';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to use our user.dto.ts and current-user.decorator of all our services we need to make sure that we export it in our &lt;code&gt;libs/common/src/index.ts&lt;/code&gt; file: update your &lt;strong&gt;index.ts&lt;/strong&gt; file with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export * from './database';
export * from './logger';
export * from './auth';
export * from './constants';
export * from './dto';
export * from './decorators';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;We're ready to integrate our newly created common JwtAuthGuard into our reservations routes to lock them down to only authenticated users.&lt;/p&gt;

&lt;p&gt;Open your reservation&lt;code&gt;main.ts&lt;/code&gt; file and update with he following content to use cookie parser middleware:&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 { ReservationsModule } from './reservations/reservations.module';
import { ValidationPipe } from '@nestjs/common';
import { Logger } from 'nestjs-pino';
import { ConfigService } from '@nestjs/config';
import * as cookieParser from 'cookie-parser';

async function bootstrap() {
  const app = await NestFactory.create(ReservationsModule);
  app.use(cookieParser());
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
    }),
  );
  app.useLogger(app.get(Logger));
  const configService = app.get(ConfigService);
  await app.listen(configService.get('PORT'));
}
bootstrap();

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

&lt;/div&gt;



&lt;p&gt;Open your reservations service (&lt;strong&gt;reservations.service.ts&lt;/strong&gt;) and replace the existing code with the following to dynamically fetch the user ID of the currently authenticated user, instead of hardcoding it.&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 { ReservationsRepository } from './reservations.repository';
import { CreateReservationDto } from './dto/create-reservation.dto';
import { UpdateReservationDto } from './dto/update-reservation.dto';

@Injectable()
export class ReservationsService {
  constructor(
    private readonly reservationsRepository: ReservationsRepository,
  ) {}

  async create(createReservationDto: CreateReservationDto, userId: string) {
    return this.reservationsRepository.create({
      ...createReservationDto,
      timestamp: new Date(),
      userId,
    });
  }

  async findAll() {
    return this.reservationsRepository.find({});
  }

  async findOne(_id: string) {
    return this.reservationsRepository.findOne({ _id });
  }

  async update(_id: string, updateReservationDto: UpdateReservationDto) {
    return this.reservationsRepository.findOneAndUpdate(
      { _id },
      { $set: updateReservationDto },
    );
  }

  async remove(_id: string) {
    return this.reservationsRepository.findOneAndDelete({ _id });
  }
}

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

&lt;/div&gt;



&lt;p&gt;Open your reservations controller (&lt;strong&gt;reservations.controller.ts&lt;/strong&gt;) and update it with the following content to utilize our common &lt;strong&gt;JwtAuthGuard&lt;/strong&gt; and retrieve the currently authenticated user data. We'll use the newly created &lt;strong&gt;CurrentUser&lt;/strong&gt; decorator with the &lt;strong&gt;UserDto&lt;/strong&gt; type, which is imported from our &lt;code&gt;@app/common&lt;/code&gt;.&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,
  Patch,
  Param,
  Delete,
  UseGuards,
} from '@nestjs/common';
import { ReservationsService } from './reservations.service';
import { CreateReservationDto } from './dto/create-reservation.dto';
import { UpdateReservationDto } from './dto/update-reservation.dto';
import { CurrentUser, JwtAuthGuard, UserDTO } from '@app/common';

@Controller('reservations')
export class ReservationsController {
  constructor(private readonly reservationsService: ReservationsService) {}

  @UseGuards(JwtAuthGuard)
  @Post()
  async create(
    @Body() createReservationDto: CreateReservationDto,
    @CurrentUser() user: UserDTO,
  ) {
    return await this.reservationsService.create(
      createReservationDto,
      user._id,
    );
  }

  @Get()
  @UseGuards(JwtAuthGuard)
  async findAll() {
    return this.reservationsService.findAll();
  }

  @Get(':id')
  @UseGuards(JwtAuthGuard)
  async findOne(@Param('id') id: string) {
    return this.reservationsService.findOne(id);
  }

  @Patch(':id')
  @UseGuards(JwtAuthGuard)
  async update(
    @Param('id') id: string,
    @Body() updateReservationDto: UpdateReservationDto,
  ) {
    return this.reservationsService.update(id, updateReservationDto);
  }

  @Delete(':id')
  @UseGuards(JwtAuthGuard)
  async remove(@Param('id') id: string) {
    return this.reservationsService.remove(id);
  }
}

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

&lt;/div&gt;



&lt;p&gt;By adding the @UseGuards(JwtAuthGuard) decorator to your route handlers, you ensure that only authenticated users can access these routes.&lt;/p&gt;




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

&lt;p&gt;In this tutorial, you learned how to add JWT-based authentication to your microservices architecture with NestJS. By creating a common JWT authentication guard, you can easily secure your routes across different services. This approach provides flexibility and reusability, allowing you to enforce authentication in a microservices environment efficiently.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>10. Implementing JWT Authentication</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Tue, 07 Nov 2023 03:27:43 +0000</pubDate>
      <link>https://dev.to/techjayvee/10-implementing-jwt-authentication-4nf0</link>
      <guid>https://dev.to/techjayvee/10-implementing-jwt-authentication-4nf0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In our previous tutorial, we set up local authentication in a Nest.js application to handle user login and authentication. Now, we'll take it a step further and implement JWT (JSON Web Token) authentication to secure routes and endpoints in our application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the JWT Strategy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Create JWT Strategy:&lt;/strong&gt; First, we need to create a JWT strategy that validates JWT tokens. Inside your auth/strategies folder, create a new TypeScript file, jwt.strategy.ts, and define the JWT strategy:&lt;br&gt;
run the command to create &lt;code&gt;jwt.strategy.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch apps/auth/src/strategies/jwt.strategy.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;populate it with the following content&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, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { UsersService } from '../users/users.service';
import { ConfigService } from '@nestjs/config';
import { Request } from 'express';
import { Tokenpayload } from '../interface/token-payload.interface';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(
    private readonly configService: ConfigService,
    private readonly userService: UsersService,
  ) {
    super({
      jwtFromRequest: ExtractJwt.fromExtractors([
        (request: Request) =&amp;gt; request.cookies.Authentication, // JWT in a cookie
      ]),
      secretOrKey: configService.get('JWT_SECRET'),
    });
  }

  async validate({ userId }: Tokenpayload) {
    return this.userService.getUser({ _id: userId });  //We will define 'getUser' in the user service later; for now, let's just declare it
  }
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating DTO for getUser
&lt;/h2&gt;

&lt;p&gt;To create &lt;code&gt;get-user.dto.ts&lt;/code&gt; inside our user/dto folder run this command on your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch apps/auth/src/users/dto/get-user.dto.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;populate it with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { IsNotEmpty, IsString } from 'class-validator';

export class GetUserDto {
  @IsString()
  @IsNotEmpty()
  _id: string;
}

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

&lt;/div&gt;



&lt;p&gt;In this DTO, we use the @IsEmail decorator to validate that the email field has a valid email format. This DTO is intended for retrieving a user by their email, and it enforces email format validation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementing getUser method in user service
&lt;/h2&gt;

&lt;p&gt;open your user.service.ts and update the content with the following code:&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, UnauthorizedException } from '@nestjs/common';
import { UserRepository } from './user.repository';
import { CreateUserDTO } from './dto/create-user.dto';
import * as bcryptjs from 'bcryptjs';
import { GetUserDto } from './dto/get-user.dto';
@Injectable()
export class UsersService {
  constructor(private readonly userRepository: UserRepository) {}

  async create(createUserDto: CreateUserDTO) {
    return this.userRepository.create({
      ...createUserDto,
      password: await bcryptjs.hash(createUserDto.password, 10),
    });
  }

  async verifyUser(email: string, password: string) {
    const user = await this.userRepository.findOne({ email });
    const passwordIsValid = await bcryptjs.compare(password, user.password);
    if (!passwordIsValid) {
      throw new UnauthorizedException('Invalid credentials');
    }
    return user;
  }

  async getUser(getUserDto: GetUserDto) {
    return this.userRepository.findOne(getUserDto);
  }
}

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

&lt;/div&gt;



&lt;p&gt;we just added a getUser method &lt;/p&gt;




&lt;h2&gt;
  
  
  Creating the JWT Auth Guard
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Create JWT Auth Guard:&lt;/strong&gt; Similar to our local authentication guard, we need an auth guard for JWT. Create a jwt-auth.guard.ts file in your guards folder to do this run this command on your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch apps/auth/src/guards/jwt-auth.guard.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;populate it with the following content:&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 { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using JWT Authentication
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use JWT Auth Guard:&lt;/strong&gt; You can use the JwtAuthGuard in your controller methods or routes to protect them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apply JWT Authentication:&lt;/strong&gt; In your controllers, you can apply JWT authentication using the @UseGuards decorator. to protect routes: For example, to protect a route that returns the current update your &lt;code&gt;user.controller.ts&lt;/code&gt; content with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDTO } from './dto/create-user.dto';
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
import { CurrentUser } from '../current-user.decorator';
import { UserDocument } from './models/user.schema';

@Controller('users')
export class UsersController {
  constructor(private readonly userService: UsersService) {}

  @Post()
  async createUser(@Body() createUserDto: CreateUserDTO) {
    return this.userService.create(createUserDto);
  }

  @Get()
  @UseGuards(JwtAuthGuard)
  getCurrentUser(@CurrentUser() user: UserDocument) {
    return user;
  }
}

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In the auth module, add the jwt strategy as a provider:&lt;br&gt;
update your auth.module.ts with the following content&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UsersModule } from './users/users.module';
import { LoggerModule } from '@app/common';
import { JwtModule } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as Joi from 'joi';
import { LocalStrategy } from './strategies/local.strategy';
import { JwtStrategy } from './strategies/jwt.strategy';

@Module({
  imports: [
    UsersModule,
    LoggerModule,
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: Joi.object({
        JWT_SECRET: Joi.string().required(),
        JWT_EXPIRATION: Joi.string().required(),
        PORT: Joi.number().required(), //we wil setup this env later
      }),
    }),
    JwtModule.registerAsync({
      useFactory: (configService: ConfigService) =&amp;gt; ({
        secret: configService.get&amp;lt;string&amp;gt;('JWT_SECRET'),
        signOptions: {
          expiresIn: `${configService.get&amp;lt;string&amp;gt;('JWT_EXPIRATION')}s`,
        },
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [AuthController],
  providers: [AuthService, LocalStrategy, JwtStrategy],
})
export class AuthModule {}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Add cookie-parser Middleware
&lt;/h2&gt;

&lt;p&gt;install cookie-parser run the following command on your terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install cookie-parser
npm install -D @types/cookie-parser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;open your auth/src/main.ts file and update it with the following content to use cookie-parser as middleware&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 { AuthModule } from './auth.module';
import { ValidationPipe } from '@nestjs/common';
import { Logger } from 'nestjs-pino';
import { ConfigService } from '@nestjs/config';
import * as cookieParser from 'cookie-parser';

async function bootstrap() {
  const app = await NestFactory.create(AuthModule);
  app.use(cookieParser());
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
    }),
  );
  app.useLogger(app.get(Logger));
  const configService = app.get(ConfigService);
  await app.listen(configService.get('PORT'));
}
bootstrap();

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Validating Unique Email during User Creation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ensure Unique Email:&lt;/strong&gt; To prevent the creation of multiple users with the same email, you can add validation during user creation. Modify your user service to validate email uniqueness before creating a new user: update your &lt;strong&gt;user.service.ts&lt;/strong&gt; with the following content:&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,
  UnauthorizedException,
  UnprocessableEntityException,
} from '@nestjs/common';
import { UserRepository } from './user.repository';
import { CreateUserDTO } from './dto/create-user.dto';
import * as bcryptjs from 'bcryptjs';
import { GetUserDto } from './dto/get-user.dto';
@Injectable()
export class UsersService {
  constructor(private readonly userRepository: UserRepository) {}

  async create(createUserDto: CreateUserDTO) {
    await this.validateCreateUserDto(createUserDto);
    return this.userRepository.create({
      ...createUserDto,
      password: await bcryptjs.hash(createUserDto.password, 10),
    });
  }

  private async validateCreateUserDto(createUserDto: CreateUserDTO) {
    try {
      await this.userRepository.findOne({ email: createUserDto.email });
    } catch (error) {
      return;
    }
    throw new UnprocessableEntityException('Email already exists');
  }

  async verifyUser(email: string, password: string) {
    const user = await this.userRepository.findOne({ email });
    const passwordIsValid = await bcryptjs.compare(password, user.password);
    if (!passwordIsValid) {
      throw new UnauthorizedException('Invalid credentials');
    }
    return user;
  }

  async getUser(getUserDto: GetUserDto) {
    return this.userRepository.findOne(getUserDto);
  }
}

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

&lt;/div&gt;



&lt;p&gt;We have just added a 'validateCreateUserDto' function to verify the existence of an email in our database, ensuring email uniqueness.&lt;/p&gt;




&lt;p&gt;With these steps, you've implemented JWT authentication in your Nest.js application, ensuring secure access to protected routes. Additionally, you've added email uniqueness validation during user creation to maintain data integrity in your user database.&lt;/p&gt;

&lt;p&gt;In the next tutorial, we'll explore more advanced authentication features and user management.&lt;/p&gt;

&lt;p&gt;Stay tuned for the next part of our Nest.js authentication series!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>9. Setting up local authentication</title>
      <dc:creator>Jayvee Ramos</dc:creator>
      <pubDate>Tue, 07 Nov 2023 03:27:31 +0000</pubDate>
      <link>https://dev.to/techjayvee/9-setting-up-local-authentication-43d6</link>
      <guid>https://dev.to/techjayvee/9-setting-up-local-authentication-43d6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we will dive into the process of setting up a secure authentication system in your NestJS application. We'll be using Passport, a popular authentication library that simplifies the authentication process. Our primary focus will be on setting up local authentication, which involves users logging in with their email and password credentials. We'll also integrate JSON Web Tokens (JWT) to secure our application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Setting Up the JWT Module
&lt;/h2&gt;

&lt;p&gt;Before we start implementing authentication, let's ensure we have a clean setup for the JWT module. Make sure you have the necessary dependencies installed and properly configured.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Creating Authentication Strategies
&lt;/h2&gt;

&lt;p&gt;Passport has the concept of strategies in NestJS, where each strategy represents a different type of authentication method. We will start by creating a local strategy for email and password-based logins. This strategy will extend the Passport strategy, so ensure you import it correctly.&lt;/p&gt;

&lt;p&gt;In your auth folder, create a new "strategies" folder to organize your authentication strategies. The first strategy we're creating is the local strategy, responsible for handling email and password-based authentication. This strategy should be an injectable class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the Local Strategy:
&lt;/h2&gt;

&lt;p&gt;So let's keep things organized in our auth folder.&lt;/p&gt;

&lt;p&gt;Let's create a new strategies folder use this command to create new directory inside our auth folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir apps/auth/src/strategies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create our first strategy file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch apps/auth/src/strategies/local.strategy.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will be the local strategy and this is going to be the strategy that allows us to log in with a user's email and password, which essentially will start off the authentication flow.&lt;/p&gt;

&lt;p&gt;Populate the &lt;code&gt;local.strategy.ts&lt;/code&gt; file with the following content&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, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-local';
import { UsersService } from '../users/users.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private userService: UsersService) {
    super({
      usernameField: 'email', // Use the email field as the username
    });
  }

  async validate(email: string, password: string): Promise&amp;lt;any&amp;gt; {
    try {
      return await this.userService.verifyUser(email, password); //We will define 'verifyUser' in the user service later; for now, let's just declare it
    } catch (error) {
      throw new UnauthorizedException(error);
    }
  }
}


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

&lt;/div&gt;



&lt;h2&gt;
  
  
  since we are using user service here make sure that in our &lt;strong&gt;user.service.module.ts&lt;/strong&gt; we add the userService in our export array like this   &lt;code&gt;exports: [UsersService],&lt;/code&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Step 3: Hashing Passwords with Bcrypt
&lt;/h2&gt;

&lt;p&gt;In your user service, it's crucial to hash passwords before storing them in the database. We'll use the Bcrypt library for secure password hashing. Start by installing Bcrypt as a dependency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Bcrypt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install bcryptjs
npm install --save-dev @types/bcryptjs

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

&lt;/div&gt;



&lt;p&gt;update your user.service.ts with the following content&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, UnauthorizedException } from '@nestjs/common';
import { UserRepository } from './user.repository';
import { CreateUserDTO } from './dto/create-user.dto';
import * as bcryptjs from 'bcryptjs';
@Injectable()
export class UsersService {
  constructor(private readonly userRepository: UserRepository) {}

  async create(createUserDto: CreateUserDTO) {
    return this.userRepository.create({
      ...createUserDto,
      password: await bcryptjs.hash(createUserDto.password, 10),
    });
  }

  async verifyUser(email: string, password: string) {
    const user = await this.userRepository.findOne({ email });
    const passwordIsValid = await bcryptjs.compare(password, user.password);
    if (!passwordIsValid) {
      throw new UnauthorizedException('Invalid credentials');
    }
    return user;
  }
}

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

&lt;/div&gt;



&lt;p&gt;What we did was hash the password before saving it in the database, and we declared 'verifyUser' because we used it in our 'local.strategy.ts' file.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Create the LocalAuthGuard
&lt;/h2&gt;

&lt;p&gt;let's create new folder inside out auth folder by running the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir apps/auth/src/guards
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;inside that folder we will create our local guard file by running the following command on your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch apps/auth/src/guards/local.auth-guard.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;populate &lt;code&gt;local.auth-guard.ts&lt;/code&gt; with the following content&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 { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;export class LocalAuthGuard extends AuthGuard('local') {}:&lt;/strong&gt; This class, LocalAuthGuard, extends the AuthGuard class and specifies the strategy 'local'. In Nest.js and Passport.js, the strategy name is used to determine which authentication strategy to apply. In this case, it's associated with a local authentication strategy, which involves verifying a user's credentials against a local database&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5:  Creating a Current User Decorator
&lt;/h2&gt;

&lt;p&gt;To easily access the currently authenticated user in your routes, create a decorator called "CurrentUser." This decorator will extract the user from the request.&lt;br&gt;
run the following command to create a &lt;code&gt;current-user.decorator.ts&lt;/code&gt; file inside our auth folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch apps/auth/src/current-user.decorator.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;populate it with the following content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { UserDocument } from './users/models/user.schema';

const getCurrentUserByContex = (ctx: ExecutionContext): UserDocument =&amp;gt; {
  return ctx.switchToHttp().getRequest().user;
};
export const CurrentUser = createParamDecorator(
  (_data: unknown, ctx: ExecutionContext) =&amp;gt; getCurrentUserByContex(ctx),
);

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;const getCurrentUserByContext = (ctx: ExecutionContext): UserDocument =&amp;gt; { ... }:&lt;/strong&gt; This function takes an ExecutionContext object as a parameter and is used to retrieve the currently authenticated user from the request context. It does so by calling ctx.switchToHttp().getRequest().user, assuming that the user object is stored in the request object under the key "user." The function is typed to return a UserDocument.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;export const CurrentUser = createParamDecorator((_data: unknown, ctx: ExecutionContext) =&amp;gt; getCurrentUserByContext(ctx));:&lt;/strong&gt; This code exports a custom parameter decorator called CurrentUser. The createParamDecorator function from Nest.js is used to create the decorator. It takes a callback function that receives two arguments: _data (unused) and ctx, the execution context. Inside this function, it calls getCurrentUserByContext(ctx) to retrieve the current user object, and this user object can be injected into the controller method when @CurrentUser() is used as a parameter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 Create Token Payload Interface
&lt;/h2&gt;

&lt;p&gt;On the next step, we will supply our JWT with a token payload, and since we are using TypeScript, it is recommended that we create an interface for our payload. Run the following command to create an 'interface' folder inside our 'auth/src' folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir apps/auth/src/interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;run this command to create a tokenPayload file inside the interface folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch apps/auth/src/interface/token-payload.interface.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;populate it with the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface Tokenpayload {
  userId: string;
}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 6: Implementing the Login Service and routes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Setup Login Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, let's implement the login service in your auth service so that we can use it in our auth controller &lt;br&gt;
update your &lt;code&gt;auth.service.ts&lt;/code&gt; with the following content&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 { UserDocument } from './users/models/user.schema';
import { Response } from 'express';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { Tokenpayload } from './interface/token-payload.interface';

@Injectable()
export class AuthService {
  constructor(
    private readonly configService: ConfigService,
    private readonly jwtService: JwtService,
  ) {}

  async login(user: UserDocument, response: Response) {
    const tokenPayload: Tokenpayload = {
      userId: user._id.toString(),
    };

    // Calculate the token expiration time by adding seconds to the current date
    const expires = new Date();
    expires.setSeconds(
      expires.getSeconds() + this.configService.get('JWT_EXPIRATION'),
    );

    const token = this.jwtService.sign(tokenPayload);

    response.cookie('Authentication', token, {
      expires: expires,
      httpOnly: true,
    });
  }
}


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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;async login(user: UserDocument, response: Response) { ... }:&lt;/strong&gt; This method is used to handle user login. It takes two parameters: user, which is of type UserDocument, and response, which is an Express Response object. In this method:&lt;/p&gt;

&lt;p&gt;It creates a **tokenPayload **object, which typically includes user-specific data. In this case, it only contains the user's _id.&lt;/p&gt;

&lt;p&gt;It calculates the token expiration time by adding the configured JWT expiration time to the current time.&lt;/p&gt;

&lt;p&gt;It signs the JWT using the JwtService provided by Nest.js.&lt;/p&gt;

&lt;p&gt;It sets the JWT as a cookie named &lt;strong&gt;'Authentication'&lt;/strong&gt; in the response, with an expiration date and the httpOnly flag, which is a common practice for securely storing JWTs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup Login Routes&lt;/strong&gt;&lt;br&gt;
update your &lt;code&gt;auth.controller.ts&lt;/code&gt; with the following content&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, Res, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalAuthGuard } from './guards/local.auth-guard';
import { CurrentUser } from './current-user.decorator';
import { UserDocument } from './users/models/user.schema';
import { Response } from 'express';

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

  @UseGuards(LocalAuthGuard)
  @Post('login')
  async login(
    @CurrentUser() user: UserDocument,
    @Res({ passthrough: true }) response: Response,
  ) {
    await this.authService.login(user, response);
    response.send(user);
  }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@UseGuards(LocalAuthGuard):&lt;/strong&gt; This decorator specifies that the login method should use the LocalAuthGuard guard. This guard likely checks the user's credentials before allowing access to the method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;async login(@CurrentUser() user: UserDocument, @Res({ passthrough: true }) response: Response) { ... }:&lt;/strong&gt; This is the login method, which is responsible for handling user login requests. &lt;br&gt;
It uses the** @CurrentUser** decorator to inject the currently authenticated user (of type UserDocument) and the Express Response object into the method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the auth module, add the local strategy as a provider:&lt;/strong&gt;&lt;br&gt;
update your auth.module.ts with the following content&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 { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UsersModule } from './users/users.module';
import { LoggerModule } from '@app/common';
import { JwtModule } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as Joi from 'joi';
import { LocalStrategy } from './strategies/local.strategy';

@Module({
  imports: [
    UsersModule,
    LoggerModule,
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: Joi.object({
        JWT_SECRET: Joi.string().required(),
        JWT_EXPIRATION: Joi.string().required(),
        PORT: Joi.number().required(), //we wil setup this env later
      }),
    }),
    JwtModule.registerAsync({
      useFactory: (configService: ConfigService) =&amp;gt; ({
        secret: configService.get&amp;lt;string&amp;gt;('JWT_SECRET'),
        signOptions: {
          expiresIn: `${configService.get&amp;lt;string&amp;gt;('JWT_EXPIRATION')}s`,
        },
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [AuthController],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 7: Testing the Authentication System
&lt;/h2&gt;

&lt;p&gt;Now that your authentication system is in place, test it by creating a user and logging in using Postman or your preferred API testing tool. Ensure you receive a JWT token in the response and that it's properly stored as an HTTP-only cookie.&lt;/p&gt;

&lt;p&gt;run &lt;code&gt;docker-compose up&lt;/code&gt; to start our application &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preconditions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your NestJS application with the authentication system is up and running.&lt;/li&gt;
&lt;li&gt;You have an API testing tool like Postman or an equivalent ready for testing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;1. User Registration:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Request:&lt;/strong&gt; Make a POST request to the registration endpoint to create a new user.&lt;br&gt;
&lt;strong&gt;URL:&lt;/strong&gt;&lt;a href="http://localhost:3001/users"&gt;http://localhost:3001/users&lt;/a&gt; (or your registration endpoint URL)&lt;br&gt;
&lt;strong&gt;Headers:&lt;/strong&gt; Set the Content-Type to application/json.&lt;br&gt;
&lt;strong&gt;Body:&lt;/strong&gt; Include a JSON payload with the user's registration details, including email and password. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "email": "user@example.com",
  "password": "securePassword123@"
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected Response:&lt;/strong&gt; You should receive a response indicating the successful creation of the user. Ensure that the password is securely hashed before storing it in the database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. User Login:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request:&lt;/strong&gt; Make a POST request to the login endpoint to authenticate the newly registered user.&lt;br&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="http://localhost:3001/auth/login"&gt;http://localhost:3001/auth/login&lt;/a&gt; (or your login endpoint URL)&lt;br&gt;
&lt;strong&gt;Headers:&lt;/strong&gt; Set the Content-Type to application/json.&lt;br&gt;
&lt;strong&gt;Body:&lt;/strong&gt; Include a JSON payload with the user's login credentials (email and password).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "email": "user@example.com",
  "password": "securePassword123@"
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected Response:&lt;/strong&gt; You should receive a response with a JWT token, and this token should also be securely stored as an HTTP-only cookie in the response. The response should also include the user's details. The JWT token can be used for subsequent authenticated requests.&lt;/p&gt;




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

&lt;p&gt;In this tutorial, we've covered the essential steps to set up a secure authentication system in your NestJS application using Passport and JWT. With local email and password-based authentication, you can now build a robust and secure user authentication process for your application. This foundation can be extended to support various authentication methods and user roles as your project evolves.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
