<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blogs By Atul]]></title><description><![CDATA[Blogs By Atul]]></description><link>https://blog.devatul.site</link><generator>RSS for Node</generator><lastBuildDate>Sun, 26 Apr 2026 17:16:21 GMT</lastBuildDate><atom:link href="https://blog.devatul.site/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Why KISS Matters in Coding]]></title><description><![CDATA[In the fast-paced world of software development, simplicity is a superpower. Hum log aksar complex solutions likh dete hain, thinking it makes us look smarter. But in reality, the best code is the one that solves the problem clearly and efficiently, ...]]></description><link>https://blog.devatul.site/kiss-principle</link><guid isPermaLink="true">https://blog.devatul.site/kiss-principle</guid><category><![CDATA[System Design]]></category><category><![CDATA[design principles]]></category><category><![CDATA[KISS Principle]]></category><category><![CDATA[low level design]]></category><dc:creator><![CDATA[Atul Kumar]]></dc:creator><pubDate>Thu, 10 Jul 2025 18:49:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1752172821967/fdb92637-361d-41ed-bd54-8159e5c55592.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the fast-paced world of software development, simplicity is a superpower. Hum log aksar complex solutions likh dete hain, thinking it makes us look smarter. But in reality, the best code is the one that solves the problem clearly and efficiently, bina kisi unnecessary drama ke. That’s exactly what the KISS principle stands for: <code>Keep It Simple, Stupid</code>. Chalo, let’s explore why this principle matters?</p>
<h2 id="heading-what-exactly-is-the-kiss-principle">What Exactly Is the KISS Principle?</h2>
<p>KISS ka full form hai Keep It Simple, Stupid. Yeh ek reminder hai ki jab tak simple solution kaam kar raha hai, tab tak usse complicated mat banao. A lot of times, we try to show off with clever code, but yaar, clever code better nahi hota. Clarity beats cleverness har baar.</p>
<h2 id="heading-why-does-kiss-matter-in-real-projects">Why Does KISS Matter in Real Projects?</h2>
<p>Simple code is easy to read.<br />Simple code is easy to debug.<br />Aur sabse important, simple code is easy to maintain in the long run.</p>
<p>Aaj tu code likhega, kal koi aur padhega. Ya shayad tu khud ek saal baad dekhe aur soch pade, “Yeh kya bakwaas likha tha maine?” KISS ensures ki aisa na ho.</p>
<h2 id="heading-when-you-dont-follow-kiss">When You Don’t Follow KISS</h2>
<p>Look at this JavaScript code:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserStatus</span>(<span class="hljs-params">isActive, hasSubscription, isBanned</span>) </span>{
  <span class="hljs-keyword">if</span> ((isActive &amp;&amp; hasSubscription) || (!isBanned &amp;&amp; hasSubscription &amp;&amp; isActive)) {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Allowed"</span>;
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Denied"</span>;
  }
}
</code></pre>
<p>In this code, the work is getting done, but the conditions are twisted in a way that can cause confusion. A new developer looking at this might get overwhelmed.</p>
<h2 id="heading-when-you-apply-kiss">When You Apply KISS</h2>
<p>Now look at this, the same function, but in KISS style:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserStatus</span>(<span class="hljs-params">isActive, hasSubscription, isBanned</span>) </span>{
  <span class="hljs-keyword">const</span> isEligible = isActive &amp;&amp; hasSubscription &amp;&amp; !isBanned;
  <span class="hljs-keyword">return</span> isEligible ? <span class="hljs-string">"Allowed"</span> : <span class="hljs-string">"Denied"</span>;
}
</code></pre>
<p>This code is very simple and clear. Any developer will immediately understand what the function is doing. No nonsense, just clean logic.</p>
<h2 id="heading-real-life-analogy">Real-Life Analogy</h2>
<p>Imagine ek dost tujhse rasta poochta hai. Agar tu shortcut aur simple rasta batayega, toh woh aasani se pahunch jayega. Lekin agar tu unnecessary twists aur turns batayega, toh woh confuse ho jayega. Code bhi aisa hi hai: simpler the path, better the result.</p>
<h2 id="heading-pro-tip">Pro Tip</h2>
<p>Code commit karne se pehle ek baar soch lena:<br /><code>Can I make this even simpler?</code><br />Agar jawab haan hai, toh kar do. Simple code se bugs kam hote hain aur team ke saath kaam karna bhi asaan ho jata hai.</p>
]]></content:encoded></item><item><title><![CDATA[Life Lessons from the Fractional Knapsack Problem]]></title><description><![CDATA[Today, I was solving a Data Structures and Algorithms (DSA) problem called the Fractional Knapsack Problem, and it got me thinking. Yeh problem sirf coding ka hissa nahi hai, balki life se bhi kaafi kuch sikha sakta hai. Let’s dive into the problem a...]]></description><link>https://blog.devatul.site/life-lessons-from-the-fractional-knapsack-problem</link><guid isPermaLink="true">https://blog.devatul.site/life-lessons-from-the-fractional-knapsack-problem</guid><category><![CDATA[DSA]]></category><category><![CDATA[dp]]></category><category><![CDATA[Life lessons]]></category><category><![CDATA[coding]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[app development]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[problem solving skills]]></category><dc:creator><![CDATA[Atul Kumar]]></dc:creator><pubDate>Thu, 12 Jun 2025 19:41:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1749756223882/f5ee9932-93b9-42ce-8f44-8176f77db827.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today, I was solving a Data Structures and Algorithms (DSA) problem called the Fractional Knapsack Problem, and it got me thinking. Yeh problem sirf coding ka hissa nahi hai, balki life se bhi kaafi kuch sikha sakta hai. Let’s dive into the problem and the life lessons it teaches us.</p>
<h3 id="heading-what-is-the-fractional-knapsack-problem"><strong>What is the Fractional Knapsack Problem?</strong></h3>
<p>In the Fractional Knapsack Problem, you have a bag (knapsack) with a limited weight capacity, and you’re given a bunch of items. Each item has a <strong>weight</strong> and a <strong>value</strong>. The goal? Fill the bag with items (or parts of items) to maximize the total value without exceeding the weight limit. Unlike the 0/1 Knapsack Problem, you can take fractions of items here. For example, if you can’t carry a whole item, you can take half of it to get half its value.</p>
<p>The trick is to prioritize items with the highest <strong>value-to-weight ratio</strong> (basically, value divided by weight). Sort the items by this ratio, and start picking from the highest ratio until the bag is full. Simple, yet powerful!</p>
<p>Ab isse life lessons kaise connect hote hain? Let’s find out!</p>
<h3 id="heading-life-lesson-1-prioritize-what-gives-you-the-most-value"><strong>Life Lesson 1: Prioritize What Gives You the Most Value</strong></h3>
<p>In the Fractional Knapsack Problem, we pick items with the highest value-to-weight ratio first. In life, this is like focusing on tasks or goals that give you the most <strong>benefit</strong> for the effort you put in.</p>
<p>Imagine you have limited time <strong>(your knapsack)</strong> and tons of things to do, studying, chilling with friends, working on a side hustle, or scrolling on Instagram. Not everything is equally important. Some activities, like studying for an exam or spending time with family, have a high <strong>value</strong> for your future or happiness. Others, like binge-watching a show, might feel good but have less long-term value.</p>
<p><strong>Takeaway</strong>: Ask yourself, <strong>Is mein kya value hai?</strong> Focus on high-value tasks first. Prioritize what moves you closer to your goals, just like picking the best items for the knapsack.</p>
<h3 id="heading-life-lesson-2-you-dont-always-need-to-do-everything-fully"><strong>Life Lesson 2: You Don’t Always Need to Do Everything Fully</strong></h3>
<p>The beauty of the Fractional Knapsack Problem is that you can take <strong>parts</strong> of an item. In life, this teaches us that we don’t always have to go all-in on everything. Sometimes, doing a little bit of something is enough.</p>
<p>For example, you want to learn guitar, code, and stay fit. But you don’t have time to master all three at once. Instead of giving up, you can do a little bit of each—practice guitar for 20 minutes, code for an hour, and go for a quick walk. This way, you’re still making progress without overloading yourself.</p>
<p><strong>Takeaway</strong>: <strong>Thoda thoda karo, par ruko mat!</strong> Small efforts add up. You don’t need to be perfect or complete everything just keep moving forward.</p>
<h3 id="heading-life-lesson-3-know-your-limits"><strong>Life Lesson 3: Know Your Limits</strong></h3>
<p>The knapsack has a weight limit, and so do we in life. Our time, energy, and resources are finite. You can’t say yes to everything every project, every party, every opportunity. Trying to do too much leads to burnout, just like overloading the knapsack makes it impossible to carry.</p>
<p>When solving the problem, you stop adding items when the bag is full. In life, learn to say "no" to things that don’t fit your capacity or align with your goals. It’s okay to set boundaries and protect your time.</p>
<p><strong>Takeaway</strong>: <strong>Apni capacity ko samjho.</strong> Don’t try to carry more than you can handle. Choose wisely and leave space for what truly matters.</p>
<h3 id="heading-life-lesson-4-greed-is-good-sometimes"><strong>Life Lesson 4: Greed is Good (Sometimes)</strong></h3>
<p>The Fractional Knapsack Problem uses a <strong>greedy approach</strong> you always pick the item with the highest value-to-weight ratio. In coding, <strong>greedy</strong> means making the best choice at each step, hoping it leads to the best overall solution.</p>
<p>In life, being "greedy" in a good way means grabbing opportunities that align with your goals. If you get a chance to learn a new skill, take a course, or meet someone inspiring, go for it! Don’t overthink the future just make the best choice in the moment.</p>
<p>But beware: Greed doesn’t always work (like in the 0/1 Knapsack Problem). So, balance your ambition with wisdom. <strong>Greedy bano, par soch samajh ke!</strong></p>
<p><strong>Takeaway</strong>: Seize the best opportunities in front of you, but think about whether they fit your bigger picture.</p>
<h3 id="heading-life-lesson-5-optimize-dont-overcomplicate"><strong>Life Lesson 5: Optimize, Don’t Overcomplicate</strong></h3>
<p>The Fractional Knapsack Problem is straightforward sort by value-to-weight ratio and fill the bag. It’s not about overthinking or trying every possible combination. In life, we sometimes make things too complicated. We stress about perfect plans or worry about every tiny detail.</p>
<p>Instead, take a step back and optimize. Break your goals into simple steps. Want to get fit? Start with a 10-minute workout. Want to ace DSA? Solve one problem a day. Keep it simple, and you’ll get to your goal faster.</p>
<p><strong>Takeaway</strong>: <strong>Zindagi ko simple rakho.</strong> Don’t overcomplicate things focus on what works and keep moving forward.</p>
<h3 id="heading-wrapping-up"><strong>Wrapping Up</strong></h3>
<p>Solving the Fractional Knapsack Problem today wasn’t just about coding it was a reminder of how to live smarter. Prioritize what matters, take small steps, respect your limits, grab good opportunities, and keep things simple. Yeh lessons coding se shuru hue, par zindagi ke har area mein kaam aayenge.</p>
<p>So, next time you're stuck on a DSA problem or feeling overwhelmed in life, remember: <strong>fill your knapsack wisely!</strong> What's one thing you're going to prioritize today? Share your thoughts in the comments, and let's keep learning together!</p>
]]></content:encoded></item><item><title><![CDATA[Let's build Chat with PDF]]></title><description><![CDATA[In this blog post, we'll walk through building a full-stack application that allows users to upload PDF documents and chat with them using AI. We'll focus primarily on the backend implementation, which handles PDF processing, vector embeddings, and A...]]></description><link>https://blog.devatul.site/lets-build-chat-with-pdf</link><guid isPermaLink="true">https://blog.devatul.site/lets-build-chat-with-pdf</guid><category><![CDATA[AI]]></category><category><![CDATA[gemini]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[qdrant]]></category><category><![CDATA[bullmq]]></category><category><![CDATA[RAG ]]></category><dc:creator><![CDATA[Atul Kumar]]></dc:creator><pubDate>Wed, 28 May 2025 09:58:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748425800752/ffe5b62f-c8bd-4dd6-9139-a98cfc4533d5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog post, we'll walk through building a full-stack application that allows users to upload PDF documents and chat with them using AI. We'll focus primarily on the backend implementation, which handles PDF processing, vector embeddings, and AI-powered chat functionality.</p>
<p>To make the PDFs searchable and chat-capable, we integrate:</p>
<ul>
<li><p><strong>LangChain</strong> for loading PDF content and generating vector embeddings</p>
</li>
<li><p><strong>Qdrant</strong> as the vector database to store and search those embeddings</p>
</li>
<li><p><strong>Gemini (Google’s LLM)</strong> for generating intelligent, context-aware responses</p>
</li>
<li><p><strong>BullMQ</strong> for handling background tasks like PDF parsing and embedding generation</p>
</li>
</ul>
<p>By the end of this post, you’ll have a robust app where users can chat with uploaded PDFs using modern AI technologies.</p>
<h2 id="heading-project-overview">Project Overview</h2>
<p>Our "Chat with PDF" application will:</p>
<ol>
<li><p>Allow users to upload PDF documents</p>
</li>
<li><p>Process and extract text from PDFs</p>
</li>
<li><p>Store document embeddings in a vector database</p>
</li>
<li><p>Enable users to ask questions about the document</p>
</li>
<li><p>Provide AI-generated responses based on the document content</p>
</li>
</ol>
<h2 id="heading-architecture">Architecture</h2>
<p>The application follows a client-server architecture with the following components:</p>
<h3 id="heading-backend-expressjs">Backend (Express.js)</h3>
<ul>
<li><p>REST API endpoints for file upload and chat</p>
</li>
<li><p>Authentication middleware using Clerk</p>
</li>
<li><p>PDF processing using LangChain</p>
</li>
<li><p>Vector storage using Qdrant</p>
</li>
<li><p>Background job processing using BullMQ and Redis</p>
</li>
<li><p>AI integration with Google's Generative AI (Gemini)</p>
</li>
</ul>
<h3 id="heading-data-flow">Data Flow</h3>
<ol>
<li><p>User uploads a PDF document</p>
</li>
<li><p>Backend stores the file and adds a processing job to the queue</p>
</li>
<li><p>Worker processes the PDF, extracts text, and stores embeddings in Qdrant</p>
</li>
<li><p>User asks questions about the document</p>
</li>
<li><p>Backend retrieves relevant context from the vector store</p>
</li>
<li><p>AI generates responses based on the retrieved context</p>
</li>
</ol>
<h2 id="heading-backend-implementation-details">Backend Implementation Details</h2>
<h3 id="heading-installation-and-setup">Installation and Setup</h3>
<p>Before diving into the Express server setup, let's install all the necessary dependencies for our backend:</p>
<pre><code class="lang-typescript"># Create a server directory <span class="hljs-keyword">if</span> not already created
mkdir -p server
cd server

# Initialize package.json
npm init -y

# Install core dependencies
npm install express cors dotenv multer

# Install PDF processing and AI dependencies
npm install <span class="hljs-meta">@langchain</span>/community <span class="hljs-meta">@langchain</span>/qdrant <span class="hljs-meta">@google</span>/generative-ai

# Install queue management
npm install bullmq

# Install authentication
npm install <span class="hljs-meta">@clerk</span>/clerk-sdk-node
</code></pre>
<h3 id="heading-express-server-setup">Express Server Setup</h3>
<p>Now that we have our dependencies installed, let's set up our Express server. The server will handle file uploads, process PDFs, and respond to chat queries.</p>
<p>Here's the pseudocode for our main server file (<strong>index.js</strong>):</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Import necessary dependencies</span>
Import Express, CORS, dotenv, ClerkExpressRequireAuth
Import multer middleware <span class="hljs-keyword">for</span> file uploads
Import BullMQ <span class="hljs-keyword">for</span> queue management
Import Gemini service <span class="hljs-keyword">for</span> embeddings

<span class="hljs-comment">// Load environment variables</span>
Load environment variables <span class="hljs-keyword">from</span> .env file

<span class="hljs-comment">// Initialize Express app</span>
Create Express app
Configure CORS
Configure <span class="hljs-built_in">JSON</span> parsing

<span class="hljs-comment">// Initialize BullMQ queue for PDF processing</span>
Create pdfProcessQueue

<span class="hljs-comment">// Authentication middleware</span>
Create authentication middleware using Clerk

<span class="hljs-comment">// Define routes</span>

<span class="hljs-comment">// File upload endpoint</span>
POST <span class="hljs-string">'/upload-file'</span>:
  - Use authentication middleware
  - Use multer middleware to handle file upload
  - Add PDF processing job to queue <span class="hljs-keyword">with</span> file path and user ID
  - Return success response

<span class="hljs-comment">// Chat endpoint</span>
POST <span class="hljs-string">'/chat'</span>:
  - Use authentication middleware
  - Extract question, user ID, and file ID <span class="hljs-keyword">from</span> request
  - Generate embeddings <span class="hljs-keyword">for</span> the question using Gemini service
  - Query vector store (Qdrant) <span class="hljs-keyword">with</span> embeddings to get relevant context
  - Format context and question <span class="hljs-keyword">for</span> AI model
  - Send formatted prompt to Google Generative AI (Gemini)
  - Return AI response

<span class="hljs-comment">// Start server</span>
Listen on specified port
Log server start message
</code></pre>
<h3 id="heading-file-upload-middleware">File Upload Middleware</h3>
<p>We'll use Multer to handle file uploads. Here's the pseudocode for our Multer configuration:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Import multer and path</span>
Import multer, path

<span class="hljs-comment">// Configure storage</span>
Create disk storage <span class="hljs-keyword">with</span>:
  - Destination: <span class="hljs-string">'./uploads/'</span>
  - Filename: Generate unique filename <span class="hljs-keyword">with</span> original extension

<span class="hljs-comment">// Create and export upload middleware</span>
Create multer instance <span class="hljs-keyword">with</span> storage configuration
Export uploadFile middleware that accepts single file <span class="hljs-keyword">with</span> field name <span class="hljs-string">'pdf'</span>
</code></pre>
<h3 id="heading-pdf-processing-queue">PDF Processing Queue</h3>
<p>We'll use BullMQ to manage the PDF processing queue. Here's the pseudocode for our queue setup:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Import BullMQ</span>
Import Queue <span class="hljs-keyword">from</span> <span class="hljs-string">'bullmq'</span>

<span class="hljs-comment">// Create and export PDF processing queue</span>
Create Queue <span class="hljs-keyword">with</span> name <span class="hljs-string">'pdfProcess'</span> and Redis connection options
Export queue
</code></pre>
<h3 id="heading-pdf-processing-worker">PDF Processing Worker</h3>
<p>The worker will process PDF files from the queue. Here's the pseudocode:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Import necessary dependencies</span>
Import Worker <span class="hljs-keyword">from</span> <span class="hljs-string">'bullmq'</span>
Import PDFLoader <span class="hljs-keyword">from</span> <span class="hljs-string">'@langchain/community'</span>
Import QdrantVectorStore <span class="hljs-keyword">from</span> <span class="hljs-string">'@langchain/qdrant'</span>
Import Gemini service <span class="hljs-keyword">for</span> embeddings

<span class="hljs-comment">// Create worker</span>
Create Worker <span class="hljs-keyword">with</span>:
  - Queue name: <span class="hljs-string">'pdfProcess'</span>
  - Redis connection options
  - Process <span class="hljs-function"><span class="hljs-keyword">function</span>:
    - <span class="hljs-title">Load</span> <span class="hljs-title">PDF</span> <span class="hljs-title">using</span> <span class="hljs-title">PDFLoader</span>
    - <span class="hljs-title">Split</span> <span class="hljs-title">documents</span> <span class="hljs-title">into</span> <span class="hljs-title">chunks</span>
    - <span class="hljs-title">Create</span> <span class="hljs-title">vector</span> <span class="hljs-title">store</span> <span class="hljs-title">using</span> <span class="hljs-title">Qdrant</span> <span class="hljs-title">with</span>:
      - <span class="hljs-title">Documents</span>
      - <span class="hljs-title">Embeddings</span> <span class="hljs-title">from</span> <span class="hljs-title">Gemini</span> <span class="hljs-title">service</span>
      - <span class="hljs-title">Namespace</span> <span class="hljs-title">based</span> <span class="hljs-title">on</span> <span class="hljs-title">user</span> <span class="hljs-title">ID</span> <span class="hljs-title">and</span> <span class="hljs-title">file</span> <span class="hljs-title">ID</span>
    - <span class="hljs-title">Log</span> <span class="hljs-title">completion</span> <span class="hljs-title">message</span>

// <span class="hljs-title">Handle</span> <span class="hljs-title">worker</span> <span class="hljs-title">events</span> (<span class="hljs-params">completed, failed</span>)</span>
</code></pre>
<h3 id="heading-gemini-service">Gemini Service</h3>
<p>We'll use Google's Generative AI for embeddings and chat responses. Here's the pseudocode:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Import Google Generative AI</span>
Import GoogleGenerativeAI, GoogleGenerativeAIEmbeddings

<span class="hljs-comment">// Initialize Google Generative AI with API key</span>
Create genAI instance <span class="hljs-keyword">with</span> API key <span class="hljs-keyword">from</span> environment variables

<span class="hljs-comment">// Create and export embeddings function</span>
Export GeminiEmbeddings <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">that</span> <span class="hljs-title">returns</span> <span class="hljs-title">GoogleGenerativeAIEmbeddings</span> <span class="hljs-title">instance</span>

// <span class="hljs-title">Create</span> <span class="hljs-title">and</span> <span class="hljs-title">export</span> <span class="hljs-title">chat</span> <span class="hljs-function"><span class="hljs-keyword">function</span>
<span class="hljs-title">Export</span> <span class="hljs-title">GeminiService</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">that</span>:
  - <span class="hljs-title">Takes</span> <span class="hljs-title">prompt</span> <span class="hljs-title">as</span> <span class="hljs-title">input</span>
  - <span class="hljs-title">Creates</span> <span class="hljs-title">Gemini</span> <span class="hljs-title">model</span> <span class="hljs-title">instance</span>
  - <span class="hljs-title">Generates</span> <span class="hljs-title">content</span> <span class="hljs-title">based</span> <span class="hljs-title">on</span> <span class="hljs-title">prompt</span>
  - <span class="hljs-title">Returns</span> <span class="hljs-title">generated</span> <span class="hljs-title">content</span></span></span></span>
</code></pre>
<h3 id="heading-environment-variables">Environment Variables</h3>
<p>Create a <strong>.env</strong> file in the server directory with the following variables:</p>
<pre><code class="lang-typescript">PORT=<span class="hljs-number">3001</span>
GOOGLE_API_KEY=your_google_api_key
QDRANT_URL=your_qdrant_url
REDIS_URL=your_redis_url
CLERK_SECRET_KEY=your_clerk_secret_key
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This backend setup creates a strong base for our "Chat with PDF" application. It manages file uploads, processes PDFs to extract and store embeddings, and uses AI to generate responses based on the PDF content and user questions.</p>
<p>Using queues ensures that PDF processing happens asynchronously, which improves the user experience. The vector store enables efficient semantic searches of PDF content, and the AI model creates natural language responses based on the retrieved context.</p>
<p>In a production setting, you should add error handling, logging, and possibly caching to enhance performance and reliability.</p>
<p>Check the full code here: <a target="_blank" href="https://github.com/showoff-today/chat-with-pdf">https://github.com/showoff-today/chat-with-pdf</a></p>
]]></content:encoded></item><item><title><![CDATA[My Journey with BullMQ: Sending Bulk Emails]]></title><description><![CDATA[Yesterday, I was working on my personal project, a web app that needed to send bulk emails to users. Everything was going smoothly until I hit a roadblock. My app was starting to slow down because it was trying to handle too many email-sending tasks ...]]></description><link>https://blog.devatul.site/my-journey-with-bullmq-sending-bulk-emails</link><guid isPermaLink="true">https://blog.devatul.site/my-journey-with-bullmq-sending-bulk-emails</guid><category><![CDATA[bullmq]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Atul Kumar]]></dc:creator><pubDate>Sat, 08 Jun 2024 14:40:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1717856910697/f70991aa-0f49-44bb-a45b-8ec27da98409.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Yesterday, I was working on my personal project, a web app that needed to send bulk emails to users. Everything was going smoothly until I hit a roadblock. My app was starting to slow down because it was trying to handle too many email-sending tasks at once. I needed a way to manage these tasks in the background without overloading my server.</p>
<p>After some research, I discovered BullMQ, a powerful library for managing queues in Node.js applications. It sounded like the perfect solution to my problem, so I decided to give it a try.</p>
<h4 id="heading-getting-started">Getting Started</h4>
<p>First things first, I needed to install BullMQ. I opened my terminal and ran:</p>
<pre><code class="lang-bash">npm install bullmq
</code></pre>
<p>Since BullMQ relies on Redis for its operations, I made sure Redis was installed and running on my machine.</p>
<h4 id="heading-creating-my-first-queue">Creating My First Queue</h4>
<p>With the installation done, it was time to create my first queue for sending bulk emails. I created a new file called <code>queue.js</code> and started coding. I imported the necessary modules from BullMQ and set up my queue:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { Queue } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'bullmq'</span>);

<span class="hljs-comment">// Create a new queue</span>
<span class="hljs-keyword">const</span> emailQueue = <span class="hljs-keyword">new</span> Queue(<span class="hljs-string">'email-queue'</span>);

<span class="hljs-comment">// Adding an email task to the queue</span>
emailQueue.add(<span class="hljs-string">'send-email'</span>, { <span class="hljs-attr">to</span>: <span class="hljs-string">'user@example.com'</span>, <span class="hljs-attr">subject</span>: <span class="hljs-string">'Hello!'</span>, <span class="hljs-attr">body</span>: <span class="hljs-string">'This is a test email.'</span> });

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Email task added to the queue'</span>);
</code></pre>
<p>I ran the file with <code>node queue.js</code>, and just like that, my first email task was added to the queue. It felt great to see my code working!</p>
<h4 id="heading-processing-email-tasks">Processing Email Tasks</h4>
<p>Next, I needed a worker to process the email tasks in the queue. I created another file called <code>worker.js</code> and wrote the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { Worker } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'bullmq'</span>);
<span class="hljs-keyword">const</span> nodemailer = <span class="hljs-built_in">require</span>(<span class="hljs-string">'nodemailer'</span>);

<span class="hljs-comment">// Configure the email transporter</span>
<span class="hljs-keyword">const</span> transporter = nodemailer.createTransport({
    <span class="hljs-attr">service</span>: <span class="hljs-string">'gmail'</span>,
    <span class="hljs-attr">auth</span>: {
        <span class="hljs-attr">user</span>: <span class="hljs-string">'your-email@gmail.com'</span>,
        <span class="hljs-attr">pass</span>: <span class="hljs-string">'your-email-password'</span>
    }
});

<span class="hljs-comment">// Create a worker to process email tasks</span>
<span class="hljs-keyword">const</span> worker = <span class="hljs-keyword">new</span> Worker(<span class="hljs-string">'email-queue'</span>, <span class="hljs-keyword">async</span> job =&gt; {
    <span class="hljs-keyword">const</span> { to, subject, body } = job.data;

    <span class="hljs-keyword">let</span> mailOptions = {
        <span class="hljs-attr">from</span>: <span class="hljs-string">'your-email@gmail.com'</span>,
        to,
        subject,
        <span class="hljs-attr">text</span>: body
    };

    <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">await</span> transporter.sendMail(mailOptions);
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Email sent to <span class="hljs-subst">${to}</span>`</span>);
    } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">`Failed to send email to <span class="hljs-subst">${to}</span>: <span class="hljs-subst">${error.message}</span>`</span>);
    }
});

worker.on(<span class="hljs-string">'completed'</span>, <span class="hljs-function">(<span class="hljs-params">job</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Email task <span class="hljs-subst">${job.id}</span> completed`</span>);
});

worker.on(<span class="hljs-string">'failed'</span>, <span class="hljs-function">(<span class="hljs-params">job, err</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Email task <span class="hljs-subst">${job.id}</span> failed with error <span class="hljs-subst">${err.message}</span>`</span>);
});
</code></pre>
<p>I ran this file using <code>node worker.js</code>, and my worker was ready to process email tasks. When I saw the messages in the console confirming the emails were sent, I felt a sense of accomplishment.</p>
<h4 id="heading-scheduling-bulk-emails">Scheduling Bulk Emails</h4>
<p>With the basics working, I decided to explore some of BullMQ's advanced features. I wanted to schedule bulk emails to be sent at a later time, so I modified my <code>queue.js</code> to add a job with a delay:</p>
<pre><code class="lang-javascript">emailQueue.add(<span class="hljs-string">'send-email'</span>, 
    { <span class="hljs-attr">to</span>: <span class="hljs-string">'user@example.com'</span>, <span class="hljs-attr">subject</span>: <span class="hljs-string">'Hello!'</span>, <span class="hljs-attr">body</span>: <span class="hljs-string">'This is a scheduled email.'</span> }, 
    { <span class="hljs-attr">delay</span>: <span class="hljs-number">5000</span> } <span class="hljs-comment">// Delays the email by 5 seconds</span>
);
</code></pre>
<p>I also wanted to track the progress of sending emails and listen for events. I updated my <code>worker.js</code>:</p>
<pre><code class="lang-javascript">worker.on(<span class="hljs-string">'progress'</span>, <span class="hljs-function"><span class="hljs-params">job</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Email task <span class="hljs-subst">${job.id}</span> is in progress`</span>);
});

worker.on(<span class="hljs-string">'completed'</span>, <span class="hljs-function"><span class="hljs-params">job</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Email task <span class="hljs-subst">${job.id}</span> completed`</span>);
});

worker.on(<span class="hljs-string">'failed'</span>, <span class="hljs-function">(<span class="hljs-params">job, err</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Email task <span class="hljs-subst">${job.id}</span> failed with error <span class="hljs-subst">${err.message}</span>`</span>);
});
</code></pre>
<h4 id="heading-conclusion">Conclusion</h4>
<p>By the end of the day, I had integrated BullMQ into my project, and it was handling the bulk email tasks efficiently. My web app was no longer slowing down, and I felt more confident in my project's scalability. BullMQ turned out to be a lifesaver, providing a robust solution to my problem with its easy-to-use API and powerful features.</p>
<p>So, if you ever find yourself needing to manage background tasks, like sending bulk emails, in your Node.js applications, give BullMQ a try.</p>
]]></content:encoded></item><item><title><![CDATA[Some common test scripts in Postman]]></title><description><![CDATA[In this article, we will look at some usual test scripts that people often use when they write test cases.
In Postman, test scripts are written using JavaScript in the "Tests" tab after sending an API request. Each test script is associated with a sp...]]></description><link>https://blog.devatul.site/some-common-test-scripts-in-postman</link><guid isPermaLink="true">https://blog.devatul.site/some-common-test-scripts-in-postman</guid><category><![CDATA[Postman]]></category><category><![CDATA[Testing]]></category><category><![CDATA[API TESTING]]></category><category><![CDATA[PostmanTesting]]></category><dc:creator><![CDATA[Atul Kumar]]></dc:creator><pubDate>Mon, 04 Sep 2023 18:40:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/FPK6K5OUFVA/upload/0df45e9ec0c00a26a69a5885f4f63bfc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we will look at some usual test scripts that people often use when they write test cases.</p>
<p>In Postman, test scripts are written using JavaScript in the "Tests" tab after sending an API request. Each test script is associated with a specific API request and is executed automatically after the request is sent. The test script has access to the response data, request details, and various utility functions provided by Postman.</p>
<p>A basic test script structure looks like this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test script</span>
pm.test(<span class="hljs-string">"Test Description"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Assertion logic goes here</span>
});
</code></pre>
<h2 id="heading-common-test-scripts"><strong>Common Test Scripts</strong></h2>
<h3 id="heading-1-status-code-validation">1. Status Code Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test if the response status code is 200 (OK)</span>
pm.test(<span class="hljs-string">"Status code is 200"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    pm.response.to.have.status(<span class="hljs-number">200</span>);
});
</code></pre>
<h3 id="heading-2-response-time-validation">2. Response Time Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test if the response time is less than 500ms</span>
pm.test(<span class="hljs-string">"Response time is within acceptable range"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    pm.expect(pm.response.responseTime).to.be.below(<span class="hljs-number">500</span>);
});
</code></pre>
<h3 id="heading-3-response-body-validation">3. Response Body Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test if the response body contains a specific value</span>
pm.test(<span class="hljs-string">"Response body contains expected data"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    pm.expect(pm.response.text()).to.include(<span class="hljs-string">"expected_value"</span>);
});
</code></pre>
<h3 id="heading-4-json-response-validation">4. JSON Response Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test if the response is a valid JSON</span>
pm.test(<span class="hljs-string">"Response is valid JSON"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    pm.expect(pm.response.json()).to.be.an(<span class="hljs-string">"object"</span>);
});
</code></pre>
<h3 id="heading-5-header-validation">5. Header Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test if a specific header is present in the response</span>
pm.test(<span class="hljs-string">"Header is present in the response"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    pm.response.to.have.header(<span class="hljs-string">"header_name"</span>);
});
</code></pre>
<h3 id="heading-6-chaining-tests">6. Chaining Tests</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Chaining multiple test assertions</span>
pm.test(<span class="hljs-string">"Chaining multiple assertions"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    pm.expect(pm.response.json().property1).to.eql(<span class="hljs-string">"value1"</span>);
    pm.expect(pm.response.json().property2).to.eql(<span class="hljs-string">"value2"</span>);
});
</code></pre>
<h3 id="heading-7-dynamic-data-validation">7. Dynamic Data Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test if a specific value in the response matches the environment variable</span>
pm.test(<span class="hljs-string">"Dynamic data validation"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    pm.expect(pm.response.json().user_id).to.eql(pm.environment.get(<span class="hljs-string">"user_id"</span>));
});
</code></pre>
<h3 id="heading-8-setting-data-from-the-environment-variable">8. Setting data from the environment variable</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> jsonData = pm.response.json();
pm.environment.set(<span class="hljs-string">"companyIdToDelete"</span>, jsonData.data._id);
</code></pre>
<h3 id="heading-9-response-schema-validation">9. Response Schema Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test if the response adheres to a specific JSON schema</span>
pm.test(<span class="hljs-string">"Response schema validation"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> schema = {
        <span class="hljs-string">"type"</span>: <span class="hljs-string">"object"</span>,
        <span class="hljs-string">"properties"</span>: {
            <span class="hljs-string">"property1"</span>: { <span class="hljs-string">"type"</span>: <span class="hljs-string">"string"</span> },
            <span class="hljs-string">"property2"</span>: { <span class="hljs-string">"type"</span>: <span class="hljs-string">"number"</span> }
        }
    };
    pm.expect(tv4.validate(pm.response.json(), schema)).to.be.true;
});
</code></pre>
<h3 id="heading-10-dynamic-response-validation">10. Dynamic Response Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Validate dynamic data in the response by extracting values from the response and using them in assertions.</span>
<span class="hljs-comment">// Extract a value from the response and use it in an assertion</span>
pm.test(<span class="hljs-string">"Dynamic response validation"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> responseBody = pm.response.json();
    <span class="hljs-keyword">var</span> dynamicValue = responseBody.dynamic_property;

    pm.expect(dynamicValue).to.equal(pm.variables.get(<span class="hljs-string">"expected_dynamic_value"</span>));
});
</code></pre>
<h3 id="heading-11-api-versioning-validation">11. API Versioning Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test different API versions</span>
<span class="hljs-keyword">var</span> apiVersion = <span class="hljs-string">"v2"</span>;
pm.test(<span class="hljs-string">"API versioning validation"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    pm.request.headers.add({ <span class="hljs-attr">key</span>: <span class="hljs-string">"Accept-Version"</span>, <span class="hljs-attr">value</span>: apiVersion });
    pm.sendRequest(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{
        pm.expect(response.status).to.equal(<span class="hljs-number">200</span>);
        pm.expect(response.json().version).to.equal(apiVersion);
    });
});
</code></pre>
<h3 id="heading-12-file-upload-validation">12. File Upload Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test file upload</span>
pm.test(<span class="hljs-string">"File upload validation"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> formData = {
        <span class="hljs-attr">file</span>: {
            <span class="hljs-attr">value</span>: pm.globals.get(<span class="hljs-string">"fileData"</span>),
            <span class="hljs-attr">options</span>: {
                <span class="hljs-attr">filename</span>: <span class="hljs-string">"sample.txt"</span>,
                <span class="hljs-attr">contentType</span>: <span class="hljs-string">"text/plain"</span>
            }
        }
    };

    pm.sendRequest({
        <span class="hljs-attr">url</span>: <span class="hljs-string">"https://api.example.com/upload"</span>,
        <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
        <span class="hljs-attr">body</span>: formData
    }, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{
        pm.expect(response.status).to.equal(<span class="hljs-number">200</span>);
        pm.expect(response.json().success).to.be.true;
    });
});
</code></pre>
<h3 id="heading-13-authentication-and-authorization-testing">13. Authentication and Authorization Testing</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test authentication and authorization</span>
pm.test(<span class="hljs-string">"Authentication and authorization"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> authToken = pm.environment.get(<span class="hljs-string">"authToken"</span>);

    pm.request.headers.add({ <span class="hljs-attr">key</span>: <span class="hljs-string">"Authorization"</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">"Bearer "</span> + authToken });
    pm.sendRequest(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{
        pm.expect(response.status).to.equal(<span class="hljs-number">200</span>);
        pm.expect(response.json().authorized).to.be.true;
    });
});
</code></pre>
<h3 id="heading-14-data-extraction-and-transformation">14. Data Extraction and Transformation</h3>
<p>Extract data from the response and transform it for further use or validation.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Extract and transform data from the response</span>
pm.test(<span class="hljs-string">"Data extraction and transformation"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> responseArray = pm.response.json().data;
    <span class="hljs-keyword">var</span> transformedData = responseArray.map(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) </span>{
        <span class="hljs-keyword">return</span> {
            <span class="hljs-attr">id</span>: item.id,
            <span class="hljs-attr">name</span>: item.first_name + <span class="hljs-string">" "</span> + item.last_name<span class="hljs-string">"
        };
    });

    // Use transformed data for assertions or environment variables
    pm.expect(transformedData[0].name).to.include("</span>John<span class="hljs-string">");
    pm.environment.set("</span>transformedData<span class="hljs-string">", JSON.stringify(transformedData));
});</span>
</code></pre>
<h3 id="heading-15-session-management">15. Session Management</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">//Simulate session management by saving and reusing session tokens.</span>
<span class="hljs-comment">// Session management using session tokens</span>
<span class="hljs-keyword">var</span> sessionToken;

pm.test(<span class="hljs-string">"Login and session management"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Perform login and extract session token from the response</span>
    sessionToken = pm.response.json().session_token;
    pm.environment.set(<span class="hljs-string">"sessionToken"</span>, sessionToken);
});

pm.test(<span class="hljs-string">"Authenticated request using session token"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Use the saved session token for authenticated requests</span>
    pm.request.headers.add({ <span class="hljs-attr">key</span>: <span class="hljs-string">"Authorization"</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">"Bearer "</span> + sessionToken });
    pm.sendRequest(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{
        pm.expect(response.status).to.equal(<span class="hljs-number">200</span>);
    });
});
</code></pre>
<h3 id="heading-16-pagination-testing">16. Pagination Testing</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Test APIs that return paginated results and validate pagination logic.</span>
<span class="hljs-comment">// Pagination testing</span>
pm.test(<span class="hljs-string">"Pagination testing"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> response = pm.response.json();
    <span class="hljs-keyword">var</span> currentPage = response.page;
    <span class="hljs-keyword">var</span> totalPages = response.total_pages;

    <span class="hljs-comment">// Validate pagination logic</span>
    pm.expect(currentPage).to.be.at.least(<span class="hljs-number">1</span>);
    pm.expect(currentPage).to.be.at.most(totalPages);
});
</code></pre>
<h3 id="heading-17-load-testing">17. Load Testing</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">//Perform load testing by sending multiple concurrent requests.</span>
<span class="hljs-comment">// Load testing with concurrent requests</span>
<span class="hljs-keyword">var</span> concurrentRequests = <span class="hljs-number">10</span>;

pm.test(<span class="hljs-string">"Load testing"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> requests = [];

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; concurrentRequests; i++) {
        requests.push(pm.sendRequest);
    }

    <span class="hljs-built_in">Promise</span>.all(requests).then(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">responses</span>) </span>{
        responses.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{
            pm.expect(response.status).to.equal(<span class="hljs-number">200</span>);
        });
    });
});
</code></pre>
<h3 id="heading-18-database-validation">18. Database Validation</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Validate API responses by comparing them with data from a database.</span>
<span class="hljs-comment">// Database validation using a mock database</span>
<span class="hljs-keyword">var</span> mockDatabase = [
    { <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">"Item 1"</span> },
    { <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">"Item 2"</span> }
];

pm.test(<span class="hljs-string">"Database validation"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> response = pm.response.json();

    mockDatabase.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) </span>{
        <span class="hljs-keyword">var</span> matchingItem = response.find(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">responseItem</span>) </span>{
            <span class="hljs-keyword">return</span> responseItem.id === item.id;
        });

        pm.expect(matchingItem.name).to.equal(item.name);
    });
});
</code></pre>
<blockquote>
<p>You can generate test cases using Postbot, which is located in the top right corner of the test case writing area.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693852750310/6660a9e2-6c8d-43af-bb08-c9821eeb5f50.png" alt /></p>
<p>You can write more complex test scripts using various assertions and conditions based on your API testing needs. Postman offers documentation and tutorials to help you learn more about writing test scripts and performing API testing effectively.</p>
]]></content:encoded></item><item><title><![CDATA[Automate the API testing with Postman.]]></title><description><![CDATA[Automated API testing with Postman is a valuable practice that helps developers and testers ensure the quality and functionality of their APIs. Postman is a user-friendly and powerful tool designed to simplify API testing and streamline the testing p...]]></description><link>https://blog.devatul.site/automate-the-api-testing-with-postman</link><guid isPermaLink="true">https://blog.devatul.site/automate-the-api-testing-with-postman</guid><category><![CDATA[APIs]]></category><category><![CDATA[Postman]]></category><category><![CDATA[PostmanTesting]]></category><dc:creator><![CDATA[Atul Kumar]]></dc:creator><pubDate>Mon, 04 Sep 2023 18:30:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/FPK6K5OUFVA/upload/0df45e9ec0c00a26a69a5885f4f63bfc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Automated API testing with Postman is a valuable practice that helps developers and testers ensure the quality and functionality of their APIs. Postman is a user-friendly and powerful tool designed to simplify API testing and streamline the testing process. This document will provide an overview of how to conduct automated API testing using Postman.</p>
<h2 id="heading-benefits-of-automated-api-testing-with-postman"><strong>Benefits of Automated API Testing with Postman:</strong></h2>
<ol>
<li><p><strong>Time Efficiency:</strong> Automating API testing with Postman saves time by running tests automatically, freeing up resources to focus on other critical tasks.</p>
</li>
<li><p><strong>Consistency:</strong> Automated testing ensures that API tests are performed consistently without manual errors, improving reliability and repeatability.</p>
</li>
<li><p><strong>Faster Feedback:</strong> Rapid execution of test scripts allows for quick feedback on API changes, enabling developers to fix issues promptly.</p>
</li>
<li><p><strong>Scalability:</strong> Postman supports testing multiple APIs simultaneously, making it suitable for projects of various sizes.</p>
</li>
<li><p><strong>Integration with CI/CD:</strong> Automated API testing can be integrated into Continuous Integration and Continuous Deployment (CI/CD) pipelines, ensuring thorough testing at every code change.</p>
</li>
</ol>
<p>If you're familiar with Postman basics, like sending requests and using collections, now let's dive into creating tests in Postman.</p>
<h1 id="heading-writing-test-cases-in-postman">Writing test cases in Postman</h1>
<p>Before writing test cases in Postman, ensure you have the following:</p>
<ol>
<li><p>Postman is installed on your system.</p>
</li>
<li><p>A basic understanding of APIs and HTTP methods.</p>
</li>
<li><p>Familiarity with JSON (JavaScript Object Notation) for response validation.</p>
</li>
</ol>
<h2 id="heading-where-to-write-test-cases"><strong>Where to write test cases.</strong></h2>
<p>In Postman, you can write and organize your test cases using the "Tests" tab within the Postman request editor. Here's how you can write test cases in Postman:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693851849518/5d4cb8ed-1264-40f2-abf3-d3724c44ca73.png" alt /></p>
<ul>
<li><p><strong>Create a Request:</strong> First, create a request by selecting the request type (GET, POST, PUT, DELETE, etc.) and entering the request URL along with any necessary headers, parameters, and request body.</p>
</li>
<li><p><strong>Navigate to the Tests Tab:</strong> After setting up the request details, click on the "Tests" tab located below the request editor. This is where you'll write your test scripts.</p>
</li>
<li><p><strong>Write Test Scripts:</strong> In the "Tests" tab, you can write JavaScript code to define your test scripts. These scripts will be executed after sending the request, and you can use them to validate the response received from the server.</p>
</li>
</ul>
<p>Here's a simple example of a test script that checks if the response status code is 201:</p>
<pre><code class="lang-javascript">pm.test(<span class="hljs-string">"Response status code is 201"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    pm.expect(pm.response.code).to.equal(<span class="hljs-number">201</span>);
});
</code></pre>
<p>You can add more test scripts to validate various aspects of the response, such as response headers, response body, specific data values, etc.</p>
<ul>
<li><p><strong>Run the Request:</strong> After writing your test scripts, you can click the "Send" button to send the request to the server. Postman will execute your test scripts and display the results in the "Tests Results" section below the request editor.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693851935540/e1a22606-9e78-4f77-8cd7-38cbb33d5924.png" alt /></p>
</li>
<li><p><strong>View Test Results:</strong> The test results will show you whether your test scripts passed or failed. If a test fails, Postman will provide information about the failure, which can help you identify the issues in your API.</p>
</li>
<li><p><strong>Organize Test Scripts:</strong> You can organize your test scripts by creating multiple requests within a Postman collection. Each request can have its own set of test scripts. Collections allow you to group related requests and tests together, making it easier to manage and run your test suite.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693851998293/62bca48a-5ef5-4193-b9a9-04ba2b244858.png" alt /></p>
<p>Remember that the examples provided here are basic illustrations. You can write more complex test scripts using various assertions and conditions based on your API testing needs.</p>
<p>Additionally, Postman offers documentation and tutorials to help you learn more about writing test scripts and performing API testing effectively.</p>
<blockquote>
<p>Refer this article for common test scripts in postman 👉 <a target="_blank" href="https://blogs.aboutatul.in/some-common-test-scripts-in-postman">Click Me</a></p>
</blockquote>
<h1 id="heading-integrate-postman-automated-testing-with-cicd">Integrate Postman automated testing with CI/CD</h1>
<p>Now We’ll learn about How to integrate Postman automated testing with CI/CD of GitHub using Newman in the Nest JS Project.</p>
<p>Integrating Postman automated testing with CI/CD using Newman involves setting up a process that allows you to run Postman collections and tests automatically as part of your Continuous Integration and Continuous Deployment (CI/CD) pipeline. Newman is a command-line tool provided by Postman that allows you to run Postman collections from the command line, making it suitable for automation in CI/CD environments.</p>
<p>I’m assuming that you have already created a collection with test cases.</p>
<p>Here's a step-by-step guide on how to integrate Postman automated testing with CI/CD using Newman.</p>
<h3 id="heading-generate-postman-collection-api-url">Generate Postman Collection API URL.</h3>
<p>For generating Postman collection API Url, Follow the given steps:</p>
<ol>
<li><p>Click on the “View More Actions“ button of the collection.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693853478196/17d80046-3320-4444-a729-e5270e53b602.png" alt /></p>
</li>
<li><p>Click on the “Share“ Option</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693853584714/7e159cc6-045a-4095-9484-7e644aff7862.png" alt /></p>
<ol>
<li>Choose the “Via API” option.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693853662085/8c7b6e81-b0bd-4fcf-80e9-62a1de43b9ef.png" alt /></p>
<ol>
<li>Copy the Postman API URL using copy button.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693853692344/f71fb7ff-9cf9-49f3-b9e6-cc70934529a1.png" alt class="image--center mx-auto" /></p>
<p>Your Collection API Generated Successfully.</p>
<h3 id="heading-configure-your-cicd-pipeline">Configure Your CI/CD Pipeline:</h3>
<ul>
<li><p>You'll need to set up a job or stage that will run your Postman tests using Newman.</p>
</li>
<li><p>In the pipeline configuration, you'll need to specify the commands to install Newman, run your tests, and possibly report the results.</p>
</li>
</ul>
<p>To configure your CI/CD pipeline, Follow the given steps:</p>
<ol>
<li>Create a <strong>.github</strong> folder in the root of the project.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693853738995/8f89ffa5-b018-42c3-a59f-45dd2ab1cc9f.png" alt /></p>
<ol>
<li><p>Create the <strong>workflows</strong> folder inside the <strong>.github</strong> folder.</p>
</li>
<li><p>Create <strong>yourFileName.yml</strong> file inside the workflows folder.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693853784120/0f19f41b-4da9-4e01-baca-53b29de6e2c4.png" alt /></p>
<ol>
<li><p>Now, write a shell script to run your Postman tests as part of the build or test phase.</p>
<pre><code class="lang-yaml"> <span class="hljs-attr">name:</span> <span class="hljs-string">Test</span> <span class="hljs-string">Nest.js</span> <span class="hljs-string">Application</span>

 <span class="hljs-attr">on:</span>
   <span class="hljs-attr">push:</span>
     <span class="hljs-attr">branches:</span>
       <span class="hljs-bullet">-</span> <span class="hljs-string">create-company</span> <span class="hljs-string">//</span> <span class="hljs-string">Replace</span> <span class="hljs-string">with</span> <span class="hljs-string">your</span> <span class="hljs-string">branch</span> <span class="hljs-string">name</span>

 <span class="hljs-attr">jobs:</span>
   <span class="hljs-attr">run-and-test:</span>
     <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
     <span class="hljs-attr">steps:</span>
       <span class="hljs-bullet">-</span> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v2</span>
       <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Node.js</span>
         <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/setup-node@v2</span>
         <span class="hljs-attr">with:</span>
           <span class="hljs-attr">node-version:</span> <span class="hljs-string">'18'</span>
       <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Nest.js</span> <span class="hljs-string">CLI</span>
         <span class="hljs-attr">run:</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span> <span class="hljs-string">-g</span> <span class="hljs-string">@nestjs/cli</span>
       <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Dependencies</span>
         <span class="hljs-attr">run:</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span>
       <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Run</span> <span class="hljs-string">Nest.js</span> <span class="hljs-string">Application</span> <span class="hljs-string">on</span> <span class="hljs-string">Localhost</span>
         <span class="hljs-attr">run:</span> <span class="hljs-string">npm</span> <span class="hljs-string">run</span> <span class="hljs-string">start:dev</span> <span class="hljs-string">&amp;</span> <span class="hljs-string">sleep</span> <span class="hljs-number">10</span>
       <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Run</span> <span class="hljs-string">API</span> <span class="hljs-string">Tests</span> <span class="hljs-string">with</span> <span class="hljs-string">Newman</span>
         <span class="hljs-attr">run:</span> <span class="hljs-string">|
           npm install -g newman
           newman run "Paste Generated Collection API Url"</span>
</code></pre>
<p> For more such articles visit: <a target="_blank" href="https://tech.pococare.com/">https://tech.pococare.com</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Start your React JS Project quickly by using Vite.JS]]></title><description><![CDATA[What is Vite JS?
Vite.js is a lightweight development server for building web applications. It is a fast development setup for building JavaScript projects, specifically Single Page Applications (SPAs) and Progressive Web Applications (PWAs). Vite.js...]]></description><link>https://blog.devatul.site/start-your-react-js-project-quickly-by-using-vitejs</link><guid isPermaLink="true">https://blog.devatul.site/start-your-react-js-project-quickly-by-using-vitejs</guid><category><![CDATA[React]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[#vite.js]]></category><dc:creator><![CDATA[Atul Kumar]]></dc:creator><pubDate>Wed, 25 Jan 2023 04:59:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674619745225/d12d8d76-633f-48f6-acfa-8a3c52280019.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>What is Vite JS?</strong></p>
<p>Vite.js is a lightweight development server for building web applications. It is a fast development setup for building JavaScript projects, specifically Single Page Applications (SPAs) and Progressive Web Applications (PWAs). Vite.js uses the native ES modules feature in modern browsers, which allows for fast and efficient development without the need for a build step or configuration. It also includes features such as hot module replacement, which allows for fast development cycles by automatically updating the browser when code changes are made. Vite.js is a simple, lightweight alternative to other development servers like webpack-dev-server, and can be used with popular front-end frameworks such as React, Vue, and Svelte.</p>
<h1 id="heading-how-to-setup-react-project-using-vitejs">How to setup React Project using Vite.js</h1>
<p>To set up a React project using Vite.js, you will need to have Node.js and npm (or yarn) installed on your computer. Once you have those, you can follow these steps:</p>
<ol>
<li><p>Please create a new directory for your project and navigate into it.</p>
</li>
<li><p>Run the following command to create a new React Project:</p>
<pre><code class="lang-bash"> npm create vite@latest &lt;your-app-name&gt;
</code></pre>
</li>
<li><p>We will be asked if we want to install the <code>create-vite@latest</code> package, we’ll choose <code>Y</code>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674620610750/80517e88-b9f0-4f8a-b3da-71898df42785.png" alt /></p>
</li>
<li><p>CLI asks for the package name, We will provide the package name.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674620820516/b61704b0-ab71-4adb-bda0-097212bb6fa8.png" alt /></p>
</li>
<li><p>CLI ask to choose a framework, we will select React by using the down arrow key.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674620938127/a60446fc-93c7-41da-a3c5-53eb11aef2ce.png" alt /></p>
</li>
<li><p>Now, the CLI asks to select a variant (JavaScript/TypeScript), let’s choose <code>JavaScript</code>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674621098139/388737c6-5648-4bae-89d4-4a3fbf250843.png" alt /></p>
</li>
<li><p>When creating a new project, Vite CLI doesn’t automatically download the dependencies, we have to do it manually. Run the following command to install dependencies.</p>
<pre><code class="lang-bash"> <span class="hljs-built_in">cd</span> &lt;your-project-name&gt;
 npm install
</code></pre>
</li>
<li><p>Run the following command to start our development server.</p>
<pre><code class="lang-bash"> npm run dev
</code></pre>
</li>
<li><p>Open the Local URL in your browser.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674621876454/5c1e678e-023d-4c81-9192-060274ee46b3.png" alt /></p>
</li>
<li><p>We are done, Our React Project is created.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674622020688/1b49140c-d640-4777-8a0f-b2578ce1be0f.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>Thanks, for reading my first blog, Follow me for such content.</p>
]]></content:encoded></item></channel></rss>