<?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" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Boring Developer on Medium]]></title>
        <description><![CDATA[Stories by Boring Developer on Medium]]></description>
        <link>https://medium.com/@boringdeveloper?source=rss-aa3473496e9a------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*IwNzrZJhRSm7HF7jecDCaA.png</url>
            <title>Stories by Boring Developer on Medium</title>
            <link>https://medium.com/@boringdeveloper?source=rss-aa3473496e9a------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 01 Jun 2026 04:24:20 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@boringdeveloper/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[What Are AI Agents? How They Work and Why They Change Everything]]></title>
            <link>https://boringdeveloper.medium.com/what-are-ai-agents-how-they-work-and-why-they-change-everything-7160eb7032ba?source=rss-aa3473496e9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/7160eb7032ba</guid>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[future-of-work]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[ai-agent]]></category>
            <dc:creator><![CDATA[Boring Developer]]></dc:creator>
            <pubDate>Sat, 30 May 2026 07:22:50 GMT</pubDate>
            <atom:updated>2026-05-30T07:22:50.074Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/632/1*R_NMKqYVPqIt6G10qGqgJw.jpeg" /></figure><p>You asked <strong>ChatGPT</strong> to help plan a trip. It gave you a list of hotels. An <strong>AI Agent</strong> would have booked the flight, reserved the room, blocked your calendar, and emailed your team — while you were still reading its first message.</p><blockquote>That’s not ChatGPT being smarter. That’s a completely different category of AI. And it’s already being used.</blockquote><p><strong>The AI you know has one big limitation</strong></p><p>For any task you throw at it, a basic AI can generate a well-organized trip itinerary — complete with flight options, hotel recommendations, car rentals, and even activity suggestions. It’ll tell you which flight is cheapest, which hotel has the best reviews, and what time you should leave for the airport.<br>But there’s a catch: it stops at suggestions. You still have to open multiple tabs, compare prices, enter your credit card details, and actually book everything yourself.</p><p><strong>This is where AI agents change the game</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/540/1*hkH_2K_8TI5RU8cwUfMjIA.jpeg" /></figure><p>Unlike traditional <strong>AI models</strong> that only predict, search, or retrieve information (often using techniques like RAG — Retrieval-Augmented Generation), AI agents take action. Instead of just showing you the cheapest hotel, an AI agent can book it for you. Instead of merely listing flight options, it can reserve your seat, add your passport details, and send you a confirmation email — all autonomously.</p><p><strong>What is an AI Agent?</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/440/1*EXitA4954Km2CE1IIXZj0w.png" /></figure><p>An AI agent is an autonomous system that perceives its environment, makes decisions, and takes actions to achieve specific goals — without requiring step-by-step human intervention.</p><p>Unlike traditional AI models that primarily predict or retrieve information, AI agents act. They can:</p><ul><li>Plan multi-step workflows (like organizing a full vacation itinerary)</li><li>Use tools (search the web, call APIs, interact with software)</li><li>Execute tasks (book flights, reserve hotels, send emails, make purchases)</li><li>Adapt based on feedback or changing conditions</li></ul><blockquote>Think of an AI agent as a digital assistant that doesn’t just tell you what to do — it actually does it for you.</blockquote><p><strong>How it works?</strong></p><ul><li><strong>Perceive &amp; Plan:</strong> Agent receives the goal, breaks it into subtasks</li><li><strong>Act &amp; Use Tools:</strong> Agent calls tools — web search, calendar, email, databases — to execute each step</li><li><strong>Check &amp; Loop:</strong> Agent evaluates if the goal is met, re-plans if not, stops when done</li></ul><blockquote>An LLM generates text. An Agent takes action. That one difference is the entire future of AI</blockquote><p><strong>Real world Examples:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/445/1*2dcBAAo2Cu2i_S-DuV4Ibg.jpeg" /></figure><ul><li>Coding Agents (Claude Code): Writes code, runs tests, debugs errors, and even deploys applications autonomously</li><li>Medical scheduling agents: Books appointments, sends reminders, coordinates with insurance, and prepares patient records</li><li>AI research assistants: Searches academic papers, extracts key findings, summarizes literature, and drafts research reports</li></ul><p><strong>Limitations of an AI Agent</strong></p><ul><li><strong>Accuracy and Reliability: </strong>AI agents can make mistakes — and when they do, the consequences can be costly. Unlike traditional software that follows deterministic rules, agents use probabilistic models that can hallucinate, misinterpret instructions, or execute incorrect actions.</li><li><strong>Security: </strong>Giving an AI agent autonomy means giving it access—to your accounts, APIs, payment methods, and sensitive data. This creates several security vulnerabilities.</li><li><strong>Cost and Complexity: </strong>Running AI agents is expensive and technically demanding. It requires computing resources which will run 24/7 so as to power on the agents. Then, there will be API costs, Infrastructure, Maintenance costs etc.</li><li><strong>Control: </strong>As agents become more autonomous, maintaining human control becomes harder. The Control over agents is one of the limitations that may let one think twice before using it, because an Agent with a Control might misalign from the goals, perform in an unpredicted way and some may include irreversible actions.</li></ul><p>There are many more limitations that also affect usage of AI Agents like: Integration Challenges, Skill gap etc. So, an AI Agent might sound some fancy robot doing all the things that you are capable of but it must be used with caution.</p><p><strong>Endnote: The Future Is Action</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/580/1*gA2HiVMYtYfiaovwyQcung.jpeg" /></figure><p>They’re not just smarter chatbots; they’re autonomous collaborators that can plan, use tools, and execute real-world actions on your behalf.</p><blockquote>AI agents represent a fundamental shift in how we interact with technology — from asking for information to delegating tasks.</blockquote><p>Yes, they have limitations. Accuracy issues, security risks, high costs, and control challenges mean we’re not quite at the point of fully hands-off automation. But the trajectory is clear: as models become more reliable, tools become better integrated, and safety frameworks mature, AI agents will move from novelty to necessity.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/573/1*MwAsormLX2u34rIgf90jdQ.jpeg" /></figure><p><strong>Missed the earlier parts of this series?</strong></p><ul><li>Part 1 — <a href="https://medium.com/@parthbissa5/large-language-models-explained-simply-no-engineering-degree-required-bded4fe3881b">It’s not thinking. It’s not searching. So what is it doing?</a></li><li>Part 2 — <a href="https://medium.com/@parthbissa5/what-is-rag-the-plain-english-guide-to-giving-ai-a-memory-5c8aa2711046">LLMs Hallucinate. Here’s the Fix Companies Are Quietly Using.</a></li><li>Part 3 — <a href="https://medium.com/@parthbissa5/fine-tuning-llm-building-personality-of-ai-fa74b8a40c0d">What is Fine-tuning? The plain English guide to giving AI a personality.</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7160eb7032ba" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fine-Tuning LLM:  Building Personality of AI]]></title>
            <link>https://boringdeveloper.medium.com/fine-tuning-llm-building-personality-of-ai-fa74b8a40c0d?source=rss-aa3473496e9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/fa74b8a40c0d</guid>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[future-of-work]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Boring Developer]]></dc:creator>
            <pubDate>Sat, 23 May 2026 11:26:58 GMT</pubDate>
            <atom:updated>2026-05-28T15:26:59.736Z</atom:updated>
            <content:encoded><![CDATA[<h3>RAG gives AI a memory. Fine-tuning gives it a personality. Here’s the difference</h3><blockquote><a href="https://medium.com/@parthbissa5/what-is-rag-the-plain-english-guide-to-giving-ai-a-memory-5c8aa2711046"><strong>Stop Hallucinations: How RAG Gives AI the Right Answer</strong></a></blockquote><p>In my <a href="https://medium.com/@parthbissa5/what-is-rag-the-plain-english-guide-to-giving-ai-a-memory-5c8aa2711046">previous blog</a>, we covered <strong>RAG</strong> — the technique that gives AI access to real, current information before it answers. It’s powerful.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/468/1*E-guVNJTOIosxYAi2SPstw.jpeg" /></figure><p>Every customer support chatbot you’ve ever used that felt weirdly on-brand — that knew the company’s tone, used the right terminology, never went off-script — was almost certainly fine-tuned. Here’s what that means.</p><p><strong>The Problem with a Generalist</strong></p><p>A base LLM like GPT-4 is trained to be good at everything — which means it’s optimised for nothing specific. We can make it write as a Lawyer, Doctor, Engineer etc. but it won’t be consistent, it won’t use your specific terminology and it won’t understand the nuances of your industry the way as specialist would.</p><p>Hiring a brilliant generalist and hoping they pick up your company culture on their own works — eventually, slowly, inconsistently. Fine-tuning is the structured onboarding that makes it stick from day one.</p><blockquote><strong>Fine-tuning</strong> doesn’t build a new AI. It takes one that already exists — and teaches it to be specifically good at your thing.</blockquote><p><strong>So what is Fine-Tuning?</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*TxJRKKV4iLw0ky3sRswJEg.jpeg" /></figure><p>Fine-tuning is the process of taking a pre-trained LLM and training it further on a smaller, specific dataset — so it becomes an expert in that domain, that tone, or that task.</p><p>A classically trained musician can play almost anything. Fine-tuning is like spending two years playing nothing but jazz. You don’t lose your classical training — you add a new fluency on top of it.</p><p><strong>Process of Fine-Tuning a Model</strong></p><ul><li><strong>Starting off with a Base Model:</strong> You don’t start from scratch, you have a pre-trained model — GPT, Claude, LLaMA — one that already understand language, grammar, reasoning and general knowledge. This is your starting point so called as Base Model.</li><li><strong>Prepare the Dataset: </strong>You gather examples of exactly what you want the model to do. If you want it to answer customer support questions in your brand’s tone — you collect hundreds or thousands of example question-and-answer pairs that represent the ideal response. This dataset is small compared to what the base model trained on — but it’s highly specific.</li><li><strong>Train on the Specific data: </strong>The model runs through your examples and adjusts its internal settings — called weights — to get better at producing exactly this type of output. It’s not memorising your examples. It’s shifting its behaviour toward your use case. After training, the model has permanently changed — it now defaults to your style, terminology, and approach.</li></ul><blockquote><strong>Fine-tuning</strong> doesn’t add information. It changes behaviour. That’s the entire distinction.</blockquote><p><strong>Where is Fine-Tuning is already being used?</strong></p><ul><li><strong>Customer Support:</strong> This is an prime example of Fine-Tuning. When a company’s chatbot consistently uses their brand voice — their specific words, their specific tone, their specific policies — that’s fine-tuning. A base LLM would give a generic helpful answer. A fine-tuned one gives the answer that sounds like it came from that company specifically</li><li><strong>Code Assistants: </strong>GitHub Copilot isn’t just a base LLM answering coding questions. It’s been fine-tuned on billions of lines of code — which is why it predicts code completions far better than a general-purpose AI would. It’s not smarter. It’s more specifically trained.</li></ul><p><strong>So which one is better RAG or Fine-Tuning?</strong></p><p>Neither. They solve different problems.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*f3Uf0RlRFfvQ7I0AJjprQQ.png" /></figure><p><strong>RAG</strong> is for when you want to have current, specific, or private information it wasn’t trained on. <strong>Fine-tuning</strong> is for when you need the AI to behave differently — to adopt a style, a tone, or a specialisation.</p><p>The most capable AI products use both. Fine-tune for behaviour. Use RAG for knowledge. Together they create something that sounds right and knows the right things.</p><blockquote><strong>RAG</strong> — gives AI new knowledge · dynamic · cheaper<br><strong>Fine-tuning</strong> — changes AI behaviour · permanent · more powerful<br><strong>Both</strong> — the gold standard for serious AI products</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/577/1*n-sQf6SZqgC25Ss9-UdYTQ.jpeg" /></figure><p>And as always, you’ll have to read my opinions</p><blockquote>What excites me about <strong>fine-tuning</strong> isn’t the technology — it’s the implication. A small team with the right data can now build an AI that’s more specialised than anything a large company could have bought five years ago. That’s a genuine shift in who gets to build what.</blockquote><p>Until we meet again!</p><blockquote>Missed Part 2? Read it here — <a href="https://medium.com/@parthbissa5/what-is-rag-the-plain-english-guide-to-giving-ai-a-memory-5c8aa2711046">What is RAG? The plain English guide to giving AI a memory</a></blockquote><blockquote>Part 4 dropping soon — AI Agents. Follow so you don’t miss it.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fa74b8a40c0d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Stop Hallucinations: How RAG Gives AI the Right Answer]]></title>
            <link>https://boringdeveloper.medium.com/what-is-rag-the-plain-english-guide-to-giving-ai-a-memory-5c8aa2711046?source=rss-aa3473496e9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/5c8aa2711046</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[productivity]]></category>
            <dc:creator><![CDATA[Boring Developer]]></dc:creator>
            <pubDate>Sun, 17 May 2026 07:44:43 GMT</pubDate>
            <atom:updated>2026-05-28T15:26:31.265Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*XibrsBlDKd5WsF3mWwqbyA.jpeg" /></figure><p>Quick heads up: this is Part 2 of a series. Part 1 covers LLMs — the thing that makes ChatGPT work. If you skipped it, this will still make sense. It’ll just make more sense if you didn’t.</p><blockquote><a href="https://medium.com/@parthbissa5/large-language-models-explained-simply-no-engineering-degree-required-bded4fe3881b">Large language models, explained simply — no engineering degree required</a></blockquote><p>In <a href="https://medium.com/@parthbissa5/large-language-models-explained-simply-no-engineering-degree-required-bded4fe3881b">Part 1</a>, we established something uncomfortable — LLMs don’t know facts. They know <strong>patterns</strong>. And sometimes those patterns produce very confident, very wrong answers. So here’s the question nobody answered: if that’s true, how are hospitals, law firms, and banks trusting these things with real decisions?</p><p>LLMs are pre-trained on massive, diverse datasets. When given an input, they tokenize the text, convert tokens into vectors (embeddings), and use transformer attention to relate those embeddings and produce the most statistically likely output. However, if relevant information didn’t exist in the model’s training data, the response can be misaligned, misleading, or even a hallucination. This is where RAG comes in. Would you like a shorter or more technical version?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/678/1*U80h_N_C7RQCOqTKvA_qBA.jpeg" /></figure><p>Every LLM has a training cutoff — a date after which it knows nothing. GPT-4’s cutoff is early 2024. Ask it about something that happened last month and it either says it doesn’t know, or fills the gap with a plausible-sounding fiction. For a chatbot recommending movies, that’s fine. For a financial advisor or a doctor, that’s dangerous.</p><blockquote>So the problem isn’t the LLM. The problem is that the <strong>LLM</strong> is working blind. <strong>RAG</strong> gives it eyes</blockquote><p><strong>RAG</strong> — Retrieval Augmented Generation — is a technique that gives an LLM access to specific, up-to-date information before it generates a response. Instead of relying only on what it learned during training, it first goes and fetches the relevant information, then answers.</p><p><strong>For better understanding —</strong> Think of the LLM as a brilliant writer who has read everything — but was locked in a room since last year. RAG is the librarian who, before the writer answers your question, runs out, grabs the most relevant documents, and slides them under the door</p><blockquote>So what actually happens when you ask a RAG-powered AI a question?</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*38s6VwCF6aApwGUwdq-u9g.jpeg" /></figure><p><strong>R — Retrieve</strong></p><p>The moment you type your question, the system doesn’t go straight to the LLM. First it searches a knowledge base — a curated collection of documents, PDFs, databases, or web pages that a company has pre-loaded. It finds the most relevant pieces of information for your question. Think of it as a very fast, very specific library search.</p><p><strong>A — Augment</strong></p><p>Those retrieved pieces of information are then attached to your original question — like a reference pack handed to the LLM alongside your query. The LLM now has your question AND the relevant context it needs to answer it accurately. It’s no longer working blind.</p><p><strong>G — Generate</strong></p><p>Now the LLM does what it does best — generates a response. But this time it’s grounding its answer in the retrieved documents, not just its training patterns. The result is an answer that’s accurate, current, and traceable back to a real source.</p><blockquote>RAG doesn’t make the LLM smarter. It gives the LLM better information to work with. The distinction matters.</blockquote><p><strong>Where RAG is being used?</strong></p><p><strong>Prime Example</strong> — When <strong>Perplexity AI</strong> answers a question and shows you the exact sources it used — that’s RAG in full view. It retrieved, it used the context, it generated, and it showed its work. This is what makes it more trustworthy than a standard ChatGPT response.</p><p>So, RAGs enable responses grounded in up-to-date sources: instead of relying solely on the model’s learned predictions (which can be outdated or incorrect), they retrieve relevant documents and synthesize answers based on that fresh evidence.</p><p>But here comes the harsh truth</p><blockquote>RAG is not a cure. It’s a significant improvement.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/665/1*vM1mMDF3JiDmj8Gdlaj6Dg.png" /></figure><p>Here’s what it still can’t fix:</p><ul><li>If the knowledge base it retrieves from has outdated or incorrect documents, the LLM will confidently use that bad information. RAG is only as good as the documents it has access to.</li><li>RAG reduces hallucination — it doesn’t eliminate it. The LLM still generates text token by token. If the retrieved context doesn’t fully answer the question, it may still fill the gap with a pattern rather than admitting it doesn’t know.</li><li>If the search component retrieves the wrong documents — or misses the relevant one — the LLM answers confidently based on irrelevant context. The quality of the retrieval step is just as important as the LLM itself.</li></ul><p>But as always I’ll share my opinion</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/468/1*teVY_2KZUp_eJkQGw7Vapg.jpeg" /></figure><blockquote>RAG is the most practical AI development of the last two years — not because it’s glamorous, but because it’s the first thing that made LLMs actually trustworthy enough for real decisions. Nobody talks about it enough.</blockquote><p>A Question for you:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/603/1*LJfm9k914T-Kb7GEGiWVww.jpeg" /></figure><blockquote>Which would you trust more — a standard ChatGPT answer, or one powered by RAG? And does knowing the difference change anything?</blockquote><p>See you soon!!!!!!</p><blockquote>Missed Part 1? Start here — <a href="https://medium.com/@parthbissa5/large-language-models-explained-simply-no-engineering-degree-required-bded4fe3881b">Large Language Models, explained simply</a></blockquote><blockquote>Next up — Part 3: <a href="https://medium.com/@parthbissa5/fine-tuning-llm-building-personality-of-ai-fa74b8a40c0d">What is Fine-tuning? The plain English guide to giving AI a personality</a></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5c8aa2711046" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Large language models, explained simply — no engineering degree required]]></title>
            <link>https://boringdeveloper.medium.com/large-language-models-explained-simply-no-engineering-degree-required-bded4fe3881b?source=rss-aa3473496e9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/bded4fe3881b</guid>
            <category><![CDATA[future-of-work]]></category>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Boring Developer]]></dc:creator>
            <pubDate>Sat, 09 May 2026 13:33:30 GMT</pubDate>
            <atom:updated>2026-05-28T15:26:02.858Z</atom:updated>
            <content:encoded><![CDATA[<p>You’ve used ChatGPT. You’ve heard people call it ‘just autocomplete.’ But if that’s true — why does it write better than most people you know? The secret is LLM or Large Language Models. It might sound as a fancy term used for some data centre but its the core of Generative AI systems. Each of the Generative AI service are using LLMs. This post will introduce to LLM in a very simplest way possible.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/521/1*tz-FrS5bVtPrFsIP3FzaEw.jpeg" /></figure><p>First of all, You don’t need to be an engineer to understand this. In fact, most engineers can’t explain it simply either. But here’s why you should care: the people who understand how this works are already making better decisions with it than everyone else.</p><p>LLMs appear in your daily life whenever you use Gmail’s Smart Compose, Grammarly’s suggestions, or Google Search’s AI‑generated answers. You also meet them in chatbots on websites, voice assistants, and tools like Microsoft Copilot that help write emails, documents, or code inside familiar apps.</p><blockquote>Large Language Model (LLM) is a type of AI Model that has ability to process natural‑language inputs and generate human‑like responses.</blockquote><p>In simpler words: an LLM can read, understand, and generate human language.</p><ul><li>It “reads” text (like a sentence or a question) and converts it into a form the computer can work with.</li><li>It “understands” the meaning and context enough to answer questions, explain ideas, or continue a conversation.</li><li>Then it “writes” back in natural language, choosing the most likely next words to form a coherent reply.</li></ul><p><strong><em>What actually happens when you hit send?</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*jhpc6PHHe7KVDHiUcrH9Yw.jpeg" /></figure><blockquote>The first thing the model does is tear your sentence apart….</blockquote><p>The first thing the model does is break your sentence down into smaller pieces called tokens — a step known as tokenization. This process takes the input text and, depending on the underlying algorithm, splits it into words, subwords, or punctuation units that the model can process numerically.</p><p>Let’s say you ask any Generative AI : Hi, How are you?</p><p>This input will be torn apart (Tokenized) as:</p><blockquote>“<strong>Hi</strong>” — “<strong>,</strong>” — “ <strong>How</strong>” — “ <strong>are</strong>” — “ <strong>you</strong>” — “<strong>?</strong>”</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*7xHSaIcNj8JFIrxpqUrFnw.jpeg" /></figure><p>You see how a simple message turned into 6 tokens, and this is just an example how tokens are created out of your inputs.</p><blockquote><em>So now the model has your sentence split into pieces. But here’s the problem — computers don’t understand pieces of text. They only understand numbers. So how does your ‘Hi’ or ‘How’ become something a machine can actually work with?</em></blockquote><p>That’s where embeddings play their part . . .</p><p>Now the tokens are converted into a list of numbers (vectors) that captures its meaning and relationships to other words. These are called <strong>Embeddings. </strong>Instead of dealing with raw text such as “king” or “apple” , the model converts each piece into a list of numbers (a vector) that captures its meaning and relationships to other words.</p><p>Now if we just revisit the Tokens we had, their Embeddings will be as follows:</p><blockquote>“<strong>Hi</strong>” — “<strong>,</strong>” — “ <strong>How</strong>” — “ <strong>are</strong>” — “ <strong>you</strong>” — “<strong>?</strong>”<br><strong>12194</strong>, <strong>11</strong>, <strong>3253</strong>, <strong>553</strong>, <strong>481</strong>, <strong>30</strong></blockquote><p>The numbers mapped to tokens (the embeddings) are not completely random, but they are initially chosen in a structured, learnable way and then adjusted during training. These values depend entirely on the specific model and its training process, so different models will assign different numerical vectors to the same token.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/580/1*2sK359Ox8Yxy5INzy0J14Q.jpeg" /></figure><blockquote>So now the model has a long list of numbers. But numbers alone mean nothing without context. ‘Hi’ and ‘Hello’ are two separate numbers — but the model needs to know they belong together, and that together they mean something specific. How does it figure that out?</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*rGLpcfbRgJLMHf_7liL5nQ.png" /></figure><p>Here comes the role of <strong>Transformers</strong></p><p>Think of it like a room full of people where everyone is talking to everyone else simultaneously. Each word in your sentence is &quot;asking&quot; every other word — how relevant are you to me? The word &quot;bank&quot; asks &quot;river&quot; and &quot;money&quot; and &quot;account&quot; — and based on your full sentence, decides which one matters. This mechanism is called <strong>self-attention,</strong> and it&#39;s what makes modern LLMs dramatically better than everything that came before them.</p><p>By the time your sentence has passed through the Transformer, every single token is no longer just a number. It&#39;s a number that understands its relationship to every other number in the sentence. Now all the embeddings are very well aware of their relation with others.</p><p>This context-aware output is what gets handed to the next stage — where the model finally generates a response.</p><blockquote>So now the model has your sentence — fully broken down, converted to numbers, and loaded with context. You’d expect it to now “think” of an answer and write it out. But that’s not what happens.</blockquote><p>It predicts one word at a time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*PJxQKBZlxojKzdDR2o-PfQ.jpeg" /></figure><p>The model looks at everything you’ve written, asks “what word most likely comes next?” — picks one, adds it to the sequence, then repeats the exact same process. Over and over, word by word, until the response is complete. There’s no plan. No outline. No destination in mind. Just one prediction at a time, each one informed by everything that came before it.</p><p>There’s actually a setting behind this called temperature. Low temperature means the model plays it safe — picking the most statistically likely word every time. High temperature means it takes risks — picking less obvious words, which makes responses feel more creative, but also less reliable. When ChatGPT sounds poetic, someone turned that dial up.</p><p>But here’s the part that changes how you should think about these tools forever:</p><blockquote>This is exactly why LLMs make things up. They’re not lying. They’re not guessing randomly. They’re doing precisely what they were built to do — predicting the most statistically likely next word. Sometimes that prediction is a fact. Sometimes it’s a very confident-sounding fiction. The model cannot tell the difference between the two.</blockquote><p>Here’s what’s wild — the model that writes your cover letter and the one that passed the bar exam are doing the exact same thing. Predicting the next token. Nothing more, nothing less.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/620/1*m0MqMyAMMDEpM4FruH9W5g.jpeg" /></figure><p>So Now, We can bust some Myths about LLM</p><ul><li><strong>It is not searching the internet.</strong> Unless explicitly connected to a search tool, an LLM has no idea what happened yesterday.</li><li><strong>It is not thinking.</strong> There’s no reasoning happening in the way your brain reasons</li><li><strong>It is not remembering you.</strong> Every new conversation starts completely blank.</li></ul><p>Last but not the least</p><p><strong>My Opinion</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*0GlUHeM4Q5X91TshLScRVw.jpeg" /></figure><p><strong>I find it more exciting — not less — knowing that there’s no magic here. Just math, scale, and a lot of clever engineering. That’s somehow more impressive than magic</strong></p><p>And A Question for you guys,</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*y-HCOgSK69lpLQwG7EuMyw.jpeg" /></figure><p><strong>Now that you know it’s predicting words, not thinking — will you use it differently?</strong></p><blockquote>This is Part 1 of the “AI in Plain English” series. Next up — Part 2: <a href="https://medium.com/@parthbissa5/what-is-rag-the-plain-english-guide-to-giving-ai-a-memory-5c8aa2711046">What is RAG? The plain English guide to giving AI a memory</a></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bded4fe3881b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[JWT Token Verification with NodeJS and JWT]]></title>
            <link>https://boringdeveloper.medium.com/jwt-token-verification-with-nodejs-and-jwt-b330daccfcd3?source=rss-aa3473496e9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/b330daccfcd3</guid>
            <category><![CDATA[json]]></category>
            <category><![CDATA[authentication]]></category>
            <category><![CDATA[jwt]]></category>
            <category><![CDATA[node-js-tutorial]]></category>
            <category><![CDATA[nodejs]]></category>
            <dc:creator><![CDATA[Boring Developer]]></dc:creator>
            <pubDate>Sat, 02 Sep 2023 10:26:39 GMT</pubDate>
            <atom:updated>2023-09-02T10:26:39.091Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Q-Irx8szCu3cBw_h" /><figcaption>Photo by <a href="https://unsplash.com/@jsalvino?utm_source=medium&amp;utm_medium=referral">John Salvino</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>In today’s digital era, securing our data and confidential information is nothing less than a paramount. Ensuring that only authorized bodies can access our secured resources is a top most priority.</p><p>Today we’ll be generating and verifying JWT Token using NodeJS and JWT. So Let’s Dive in 🔥</p><h3>Tools We’ll be using are as follows</h3><ul><li><strong>VSCode </strong>— Code Editor 🟦<br><a href="https://code.visualstudio.com/">https://code.visualstudio.com/</a></li><li><strong>Insomnia</strong>- For testing our APIs (<strong>You can use postman too</strong>) 🟪<br><a href="https://insomnia.rest/">https://insomnia.rest/</a></li></ul><h3>Languages and Frameworks</h3><ul><li><strong>NodeJS- </strong>For creating our server and handling requests and responses using Typescript/Javascript<br><a href="https://nodejs.org/en">https://nodejs.org/en</a></li></ul><h3>Starting up with Dependencies</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*bpRTxnrlonDE4FJ8" /><figcaption>Photo by <a href="https://unsplash.com/@toddquackenbush?utm_source=medium&amp;utm_medium=referral">Todd Quackenbush</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><ul><li>Making project directory and initializing our project</li></ul><pre>mkdir tokenapi<br>npm init</pre><ul><li>Installing dependencies</li></ul><pre>npm install express body-parser jsonwebtoken</pre><h3>Let’s Create our server</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*WNz_zn0QfmU8QMu1" /><figcaption>Photo by <a href="https://unsplash.com/@ianjbattaglia?utm_source=medium&amp;utm_medium=referral">Ian Battaglia</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><ul><li>Open the project directory inside VSCode</li><li>Create a file named <strong>index.js</strong></li><li>Let’s start with importing the required dependencies in <strong>index.js</strong> file</li></ul><pre>const express = require(&#39;express&#39;)<br>const bodyparser = require(&#39;body-parser&#39;)<br>const jwt = require(&#39;jsonwebtoken&#39;)</pre><ul><li>Initializing Express server using express dependency</li></ul><pre>const app = express() // Application object over which our server will be working on<br>const port = 1973//Server port<br><br>app.use(bodyparser.urlencoded({extended: false}));<br>app.listen(port,()=&gt;{<br>    console.log(&#39;Listening to port&#39;,port) <br>})</pre><h3>Defining Routes for Generating and Verifying our Tokens</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*GLSVDQj_O00ru5oV" /><figcaption>Photo by <a href="https://unsplash.com/@foxxmd?utm_source=medium&amp;utm_medium=referral">Matt Duncan</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><ul><li>For Generating Token</li></ul><pre>app.post(&quot;/generateToken&quot;, (req, res) =&gt; {<br>    let data = {<br>        time: Date(),<br>        tokenId : 1<br>    }<br>    const token = jwt.sign(data, &#39;secret-key&#39;);<br>    res.json({&#39;secret-key&#39; : token})<br>});</pre><ul><li>For Validating Token</li></ul><pre>app.get(&quot;/validateToken&quot;, (req, res) =&gt; {<br>    try {<br>        const token = req.header(&quot;token&quot;);<br>        const verified = jwt.verify(token, &#39;secret-key&#39;);<br>        if(verified){<br>            return res.json({&#39;result&#39; : &#39;Token verified successfully&#39;})<br>        }else{<br>            return res.json({&#39;result&#39; : &#39;Token verification failed&#39;})<br>        }<br>    } catch (error) {<br>        console.log(error)<br>        return res.json({&#39;result&#39; : &#39;Something went wrong&#39;})<br>    }<br>});</pre><h3>Testing our APIs</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*_tcvI9gbWMQiljSm" /><figcaption>Photo by <a href="https://unsplash.com/@thisisengineering?utm_source=medium&amp;utm_medium=referral">ThisisEngineering RAEng</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><ul><li>Get Token using generateToken Request</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BayBBDJj7bPLsKyZatpQEg.png" /></figure><ul><li>Verifying Token using validateToken Request</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Okbi74PfBRAogPFDEABOcw.png" /></figure><h3>Conclusion</h3><p>JWT token validation is a crucial aspect of securing your Node.js applications. By following these steps, you can implement JWT-based authentication and authorization to protect your resources and ensure that only authorized users can access them. Remember to keep your secret keys secure and consider using libraries and best practices for enhanced security.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*sr_fjQNRVB5SnL4U" /><figcaption>Photo by <a href="https://unsplash.com/@flyd2069?utm_source=medium&amp;utm_medium=referral">FLY:D</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b330daccfcd3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building-up CRUD API using NodeJS | Express and PostgreSQL]]></title>
            <link>https://boringdeveloper.medium.com/building-up-crud-api-using-nodejs-express-and-postgresql-c83f34fe37f3?source=rss-aa3473496e9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/c83f34fe37f3</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[expressjs]]></category>
            <category><![CDATA[crud]]></category>
            <dc:creator><![CDATA[Boring Developer]]></dc:creator>
            <pubDate>Sat, 26 Aug 2023 17:05:58 GMT</pubDate>
            <atom:updated>2023-08-26T17:05:58.681Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Q9Z3E-h104b9VdCW" /><figcaption>Photo by <a href="https://unsplash.com/@gamell?utm_source=medium&amp;utm_medium=referral">Joan Gamell</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Hey Folks! Today, we’re going to dive into the world of backend development and explore how we can create a CRUD (Create, Read, Update, Delete) API using Node.js, Express, and PostgreSQL. CRUD operations are like the backbone of many web applications out there as they enable you to create, read, update, and delete data from database. So without wasting time, Let’s dive in! 💚🚀</p><h3><strong>Tools We’ll be using are as follows</strong></h3><ul><li><strong>VSCode </strong>— Code Editor 🟦<br><a href="https://code.visualstudio.com/">https://code.visualstudio.com/</a></li><li><strong>Insomnia</strong>- For testing our APIs (<strong>You can use postman too</strong>) 🟪<br><a href="https://insomnia.rest/">https://insomnia.rest/</a></li><li><strong>pgAdmin</strong>- For easily accessing our database using graphical inteface provided by PostgreSQL (<strong>Optional</strong>)<br><a href="https://www.postgresql.org/">https://www.postgresql.org/</a></li></ul><h3><strong>Languages and Frameworks</strong></h3><ul><li><strong>NodeJS- </strong>For creating our server and handling requests and responses using Typescript<br><a href="https://nodejs.org/en">https://nodejs.org/en</a></li><li><strong>SQL- </strong>For creating our database</li></ul><p>Before continuing further, make sure you have all these tools installed on your system</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*V4qm-aw0eJCplmz5" /><figcaption>Photo by <a href="https://unsplash.com/@wasdrew?utm_source=medium&amp;utm_medium=referral">Andras Vas</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>Starting up with Dependencies</h3><ul><li>Making project directory and initializing our project</li></ul><pre>mkdir shoppingapi<br>npm init</pre><ul><li>Installing dependencies</li></ul><pre>npm install express body-parser pg</pre><h3>Setting up our database</h3><ul><li>Creating and Connecting to our database</li></ul><pre>psql<br>CREATE database shoppingapi<br>\c shoppingapi</pre><ul><li>Creating table inside our database</li></ul><pre>CREATE TABLE product(<br>  id serial PRIMARY KEY,<br>  name VARCHAR(255) NOT NULL,<br>  price VARCHAR(255) NOT NULL<br>);</pre><ul><li>id: A unique serial integer acting as our primary key to uniquely identify items.</li><li>name: A text column for the product&#39;s name, which cannot be null.</li><li>price: A text column for the product&#39;s price, which cannot be null.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qTmvEZqS780ADcqF" /><figcaption>Photo by <a href="https://unsplash.com/@wocintechchat?utm_source=medium&amp;utm_medium=referral">Christina @ wocintechchat.com</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>Let’s Create our server</h3><ul><li>Open the project directory inside VSCode</li><li>Create a file named <strong>index.ts</strong></li><li>Importing the required dependencies</li></ul><pre>import Express, { Application, Request, Response  } from &quot;express&quot;;<br>import bodyparser from &#39;body-parser&#39;;</pre><ul><li>Initializing Express server using express dependency</li></ul><pre>const app: Application = Express() // Application object over which our server will be working on<br>const port = 8000 //Server port<br><br>app.use(bodyparser.json()) //Using body-parser for JSON parsing and other stuffs<br>app.use(<br>    bodyparser.urlencoded({<br>    extended: true,<br>  })<br>)</pre><ul><li>Running our server</li></ul><pre>app.listen(port,()=&gt;{<br>    console.log(&#39;Listening to port&#39;,port)<br>    initDB();<br>})</pre><ul><li>We are all set with our server so now let’s connect our database for implementing CRUD operations</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*AOXw4xcjqSt8RKZn" /><figcaption>Photo by <a href="https://unsplash.com/@geraninmo?utm_source=medium&amp;utm_medium=referral">Geranimo</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>Connecting PostgreSQL database to our server</h3><ul><li>Create a file named dbservice.ts where we will be inserting all database related functions</li><li>Import Client from PG dependency and initializing our database client request</li></ul><pre>import {Client} from &#39;ts-postgres&#39;<br>const pool = new Client(<br>    {<br>        user: &#39;YOUR USERNAME&#39;,<br>        password: &#39;YOUR PASSWORD&#39;,<br>        database: &#39;YOUR DATABASE NAME&#39;,<br>        host: &#39;localhost&#39;,<br>        port: &#39;YOUR PORT&#39; (5432 is default port)<br>    }<br>);<br>//initDB function to connect to our Database once before making requests<br>export const initDB =async function(){<br>  await pool.connect();<br>}</pre><ul><li>Implementing CRUD Operations</li></ul><pre>//GET ALL PRODUCTS FROM PRODUCTS TABLE<br>export const getAllProductQuery = async function () {<br>    return new Promise(async function (resolve, reject) {<br>       try{<br>        const result = await pool.query(&#39;SELECT * FROM products&#39;);<br>        resolve(result.rows);<br>       }<br>       catch(e){<br>        console.log(&#39;Error -- $e&#39;,[e])<br>        reject(e);<br>       }        <br> })}<br><br>//GET SINGLE PRODUCT FROM PRODUCT TABLE BY USING PRODUCT&#39;S ID<br>export const getProductViaId = async function (id:number) {<br>    console.log(id);<br>    return new Promise(async function (resolve, reject) {<br>       try{<br>        const result = await pool.query(&#39;SELECT * FROM products WHERE id = $1&#39;, [id])<br>        resolve(result.rows);<br>       }<br>        catch(e){<br>            console.log(&#39;Error -- $e&#39;,[e])<br>            reject(e);<br>        }<br>}<br><br>//INSERTING A PRODUCT TO PRODUCT TABLE<br>export const insertProduct = function (productName:string,productPrice:string) {<br>    return new Promise(async function (resolve, reject) {<br>        try{<br>            const result = await pool.query(&#39;INSERT INTO products (name,price) VALUES($1,$2) RETURNING *&#39;, [productName,productPrice])<br>            resolve(result.rows);<br>        }<br>        catch(e){<br>            console.log(e);<br>        }<br>    });<br>    <br>}<br><br>//UPDATING A PRODUCT INSIDE PRODUCT TABLE<br>export const updateProduct = async function (productName:string,productPrice:string,id:number) {<br>    return new Promise(async function (resolve, reject) {<br>        try{<br>            const result = await pool.query(&#39;UPDATE products SET name = $1, price = $2 WHERE id = $3&#39;, [productName,productPrice,id])<br>            resolve(result.rows);<br>        }<br>        catch(e){<br>            console.log(e);<br>            reject(e);<br>        }    <br>    });<br>}<br><br>//DELETING A PRODUCT FROM PRODUCT TABLE<br>export const deleteProduct = async function (id:number) {<br>    return new Promise(async function (resolve, reject) {<br>        try{<br>            const result = await pool.query(&#39;DELETE FROM products WHERE id = $1&#39;, [id])<br>            resolve(result.rows);<br>        }<br>        catch(e){<br>            console.log(e);<br>            reject(e);<br>        }<br>    });<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*5PgfiFdChvcRigoo" /><figcaption>Photo by <a href="https://unsplash.com/@mattseymour?utm_source=medium&amp;utm_medium=referral">Matt Seymour</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>Defining our Routes</h3><ul><li>Create a file named routes.ts where we will be defining our routes</li></ul><pre>import {deleteProduct, getAllProductQuery, getProductViaId, insertProduct, updateProduct} from &#39;./dbservice&#39;;<br>import { Response,Request } from &#39;express&#39;;<br><br>//[GET] -- ALL PRODUCTS ROUTE<br>export const allProductsRoute = (req:Request,res: Response)=&gt;{<br>   getAllProductQuery().then((value)=&gt;{<br>    res.status(200).json(value);<br>    console.log(value);<br>   });       <br>}<br><br><br>//[GET] -- GET PRODUCT BY ID ROUTE<br>export const getProductById = (req:Request,res: Response)=&gt;{<br>    const id = parseInt(req.params.id)<br>    getProductViaId(id).then((value)=&gt;{<br>        res.status(200).json(value);<br>    });<br>}<br><br>//[POST] -- INSERT PRODUCT ROUTE<br>export const insertProductRoute = (req:Request,res: Response)=&gt;{<br>    const {name,price} = req.body;<br><br>    console.log(&#39;--- $1 $2 ---&#39;,[name,price]);<br>    if(name &amp;&amp; price){<br>        insertProduct(name,price).then((value)=&gt;{<br>            res.status(200).json(value);<br>        });<br>    }<br>    else{<br>        res.status(400).json({<br>            &quot;error&quot;: &quot;Invalid inputs&quot;<br>        });<br>    }<br>}<br><br>//[GET] -- UPDATE PRODUCT ROUTE<br>export const updateProductRoute = (req:Request,res: Response)=&gt;{<br>    const {name,price} = req.body;<br>    const id = parseInt(req.params.id);<br><br>    console.log(&#39;--- $1 $2 ---&#39;,[name,price]);<br>    if(name &amp;&amp; price){<br>        updateProduct(name,price,id).then((value)=&gt;{<br>            res.status(200).json(value);<br>        });<br>    }<br>    else{<br>        res.status(400).json({<br>            &quot;error&quot;: &quot;Invalid inputs&quot;<br>        });<br>    }<br>}<br><br>//[GET] -- DELETE PRODUCT ROUTE<br>export const deleteProductRoute = (req:Request,res: Response)=&gt;{<br>    const id = parseInt(req.params.id);<br>    if(id){<br>        deleteProduct(id).then((value)=&gt;{<br>            res.status(200).json(value);<br>        });<br>    }<br>    else{<br>        res.status(400).json({<br>            &quot;error&quot;: &quot;Invalid inputs&quot;<br>        });<br>    }<br>}<br><br></pre><ul><li>Now in our index.ts file we will attach our routes to our express application</li></ul><pre>app.get(&#39;/products&#39;, (req: Request,res:Response)=&gt;{<br>  allProductsRoute(req,res)<br>})<br>app.get(&#39;/products/:id&#39;,(req: Request,res:Response)=&gt;{<br>  getProductById(req,res)<br>})<br>app.post(&#39;/insertProduct&#39;,(req: Request,res:Response)=&gt;{<br>  insertProductRoute(req,res)<br>})<br><br>app.put(&#39;/updateProduct/:id&#39;,(req:Request,res:Response)=&gt;{<br>  updateProductRoute(req,res)<br>})<br><br>app.delete(&#39;/deleteProduct/:id&#39;,(req:Request,res:Response)=&gt;{<br>  deleteProductRoute(req,res);<br>})</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Lg3jceNknPp2agTF" /><figcaption>Photo by <a href="https://unsplash.com/@sigmund?utm_source=medium&amp;utm_medium=referral">Sigmund</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3><strong>Testing our CRUD API</strong></h3><ul><li>Start the server by running following command</li></ul><pre>npm start</pre><ul><li>Open Postman/Insomnia</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OHZ91fZpTJ79D9nthh0rZQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pHhFbBx-LvI352GwXpcAcg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Z2gDdVs5bgZIZOqBeBFvDQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*l_7b69KMJo8Hwwfxh1BjCg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sMTyvUsIsDYHUQAp_eadIg.png" /></figure><h3>Conclusion</h3><p>Congratulations! You’ve just built a CRUD API using Node.js, Express, and PostgreSQL. This is a fundamental skill for backend development and will serve as the backbone for more complex applications.</p><p>Remember, this is just the beginning. You can expand on this project by adding authentication, validation, error handling, and more. The possibilities are endless, so keep exploring and building.</p><p>Happy coding, and may your CRUD operations always return the data you expect!💚🚀</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*R2Jnpn-I49a4_Ivr" /><figcaption>Photo by <a href="https://unsplash.com/@emilymorter?utm_source=medium&amp;utm_medium=referral">Emily Morter</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c83f34fe37f3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Standard Counter Application using Riverpod in Flutter]]></title>
            <link>https://boringdeveloper.medium.com/standard-counter-application-using-riverpod-in-flutter-8d246f6b5bfb?source=rss-aa3473496e9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/8d246f6b5bfb</guid>
            <category><![CDATA[flutter]]></category>
            <category><![CDATA[flutter-widget]]></category>
            <category><![CDATA[flutter-riverpod]]></category>
            <category><![CDATA[flutter-app-development]]></category>
            <category><![CDATA[flutter-ui]]></category>
            <dc:creator><![CDATA[Boring Developer]]></dc:creator>
            <pubDate>Wed, 25 Aug 2021 05:32:05 GMT</pubDate>
            <atom:updated>2021-08-25T05:32:05.451Z</atom:updated>
            <content:encoded><![CDATA[<p>Hey! guys Welcome back again!</p><p>Today I will show you how we can modify the standard counter application using the <strong>Riverpod </strong>State Management package and make it a little modern.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lHVz-zbOMa2kYmZ8rbauTA.jpeg" /></figure><p><strong>Let’s Look at what Riverpod is…</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/851/1*m6wPdUK2w1MFrQwKosDayg.png" /></figure><p>As stated above,<strong> Riverpod </strong>is a state management package used to manage the state of an application. In Flutter we have seen packages like provider, getx, bloc, etc.. and just like them, <strong>Riverpod</strong> is also a package that is used to read or listen to state changes inside an application.</p><p>Why <strong>Riverpod</strong>?<strong><em>[RIVERPOD VS PROVIDER]</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/970/1*xNXrIods0O8mhzDElNJuTA.jpeg" /></figure><p>The <strong>provider</strong> is a great package and is preferred everywhere when it comes to state management strategies but the <strong>Provider</strong> has some disadvantages in it like when we create nested providers we can only access the value of the <strong>provider</strong> which is nearest or closest. For example :</p><blockquote>class Home extends StatelessWidget{</blockquote><blockquote>Widget build(BuildContext context){</blockquote><blockquote>return Provider(</blockquote><blockquote>create : (context)=&gt; ‘FAR’</blockquote><blockquote>child Provider(</blockquote><blockquote>create : (context)=&gt; ‘CLOSE’</blockquote><blockquote>builder(context,child){</blockquote><blockquote>return Text(Provider.of&lt;String&gt;(context);</blockquote><blockquote>}</blockquote><blockquote>)</blockquote><blockquote>);</blockquote><blockquote>}</blockquote><p>Wait! if you don&#39;t know how to use providers I have already made a blog on that in which I made this application using provider so you can have a look at that :</p><p><a href="https://medium.com/@parthbissa5/the-evolution-of-counter-app-using-provider-in-flutters-83e94589c1e7">The Evolution of Counter App Using Provider in Flutters</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/236/1*7FxCa7AMEytj9t1TmCLRug.jpeg" /></figure><p>So in the above code, we have 2 providers which are providing different strings and we want to print those strings but in this case, we can only print ‘CLOSE’ because it&#39;s the nearest or the closest and that’s where we observe a small but noticeable disadvantage of the provider and also provider always shows error in runtime. Hence, to get rid of this we can use <strong>riverpod </strong>because it provides us with global providers hence we don’t have to attach providers to widgets or UI, rather than this, we will declare a provider globally and use it where we need but How?</p><p>First thing first let’s make a flutter project which will provide us the Standard Counter Application. So run the command written below</p><blockquote>flutter create riverpodtutorial</blockquote><p>So first of all let’s just remove all the boilerplate code(comments) which come whenever we make a project with flutter and then convert the MyHomePage class from stateful to stateless. Now let’s apply <strong>riverpod </strong>to the application but before that add the latest version available of the <strong>flutter_riverpod</strong> package to our pubspec.yaml file.</p><blockquote><strong>flutter_riverpod</strong> : ^latest_version</blockquote><p>So as I described above we will declare a global provider but before that, we will make a file named counterValue.dart that will have 3 very important things :</p><ol><li>Counter Value</li><li>Increment Function</li><li>Decrement Function</li></ol><p>And it will look like this :</p><blockquote>import ‘package:flutter/cupertino.dart’;</blockquote><blockquote>import ‘package:flutter/foundation.dart’;</blockquote><blockquote>class CounterValue extends ChangeNotifier {</blockquote><blockquote>int counter = 0;</blockquote><blockquote>int get <em>getCounterValue</em> =&gt; counter;</blockquote><blockquote>void <em>increment</em>() {</blockquote><blockquote>counter += 1;</blockquote><blockquote><em>notifyListeners</em>();</blockquote><blockquote>}</blockquote><blockquote>void <em>decrement</em>() {</blockquote><blockquote>counter -= 1;</blockquote><blockquote><em>notifyListeners</em>();</blockquote><blockquote>}</blockquote><blockquote>}</blockquote><p>Now we can declare a provider which will listen to the value of the counter and will be able to call both of these functions. Let’s declare our provider below main() function like this :</p><blockquote>void main(){</blockquote><blockquote>runApp(MyApp());</blockquote><blockquote>}</blockquote><blockquote>final counterProvider = ChangeNotifierProvider((ref)=&gt;CounterValue());</blockquote><p>Now we can use this counterProvider anywhere in our project so let’s use it and modify the counter app. We will add a ProviderScope to our MaterialApp and then we will be able to use the <strong>provider </strong>inside of our application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/235/1*mSvHEgwNOFEWpchwr2n6tg.jpeg" /></figure><blockquote>class MyApp extends StatelessWidget {</blockquote><blockquote>@override</blockquote><blockquote>Widget <em>build</em>(BuildContext context) {</blockquote><blockquote>return ProviderScope(</blockquote><blockquote>child: MaterialApp(</blockquote><blockquote>title: ‘Flutter Demo’,</blockquote><blockquote>debugShowCheckedModeBanner: false,</blockquote><blockquote>theme: ThemeData(</blockquote><blockquote>primarySwatch: Colors.green,</blockquote><blockquote>),</blockquote><blockquote>home: MyHomePage(),</blockquote><blockquote>),</blockquote><blockquote>);</blockquote><blockquote>}</blockquote><blockquote>}</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*n03calkUcf2hV9xYKBvYog.jpeg" /></figure><p>Now inside our HomePage class, we will cut the Text widget which shows the counter value, and replace it with a Consumer, and inside the consumer’s builder, we will paste that Text widget.</p><blockquote>Consumer(</blockquote><blockquote>builder: (builder, counter, child) {</blockquote><blockquote>final count = <em>counter</em>(counterProvider);</blockquote><blockquote>return Text(count.counter.<em>toString</em>(),</blockquote><blockquote>style: Theme.<em>of</em>(context).textTheme.headline4);</blockquote><blockquote>},</blockquote><blockquote>),</blockquote><p>And thereafter we will make two floating buttons and call those increment and decrement functions we created above.</p><blockquote>Row(</blockquote><blockquote>mainAxisAlignment: MainAxisAlignment.center,</blockquote><blockquote>children: [</blockquote><blockquote>FloatingActionButton(</blockquote><blockquote>onPressed: () {</blockquote><blockquote>context.<em>read</em>(counterProvider).<em>increment</em>();</blockquote><blockquote>},</blockquote><blockquote>tooltip: ‘Increment’,</blockquote><blockquote>child: Icon(Icons.exposure_plus_1),</blockquote><blockquote>),</blockquote><blockquote>SizedBox(</blockquote><blockquote>width: 20,</blockquote><blockquote>),</blockquote><blockquote>FloatingActionButton(</blockquote><blockquote>onPressed: () {</blockquote><blockquote>context.<em>read</em>(counterProvider).<em>decrement</em>();</blockquote><blockquote>},</blockquote><blockquote>tooltip: ‘Decrement’,</blockquote><blockquote>child: Icon(Icons.exposure_minus_1),</blockquote><blockquote>),</blockquote><blockquote>],</blockquote><blockquote>)</blockquote><p>And that’s it we have applied Riverpod to our application so let’s have a look at the complete code of this app.</p><blockquote>import ‘dart:developer’;</blockquote><blockquote>import ‘package:flutter/material.dart’;</blockquote><blockquote>import ‘package:flutter_riverpod/flutter_riverpod.dart’;</blockquote><blockquote>import ‘package:pro/counterValue.dart’;</blockquote><blockquote>void <em>main</em>() {</blockquote><blockquote><em>runApp</em>(MyApp());</blockquote><blockquote>}</blockquote><blockquote>final counterProvider = ChangeNotifierProvider((ref) =&gt; CounterValue());</blockquote><blockquote>class MyApp extends StatelessWidget {</blockquote><blockquote>@override</blockquote><blockquote>Widget <em>build</em>(BuildContext context) {</blockquote><blockquote>return ProviderScope(</blockquote><blockquote>child: MaterialApp(</blockquote><blockquote>title: ‘Flutter Demo’,</blockquote><blockquote>debugShowCheckedModeBanner: false,</blockquote><blockquote>theme: ThemeData(</blockquote><blockquote>primarySwatch: Colors.green,</blockquote><blockquote>),</blockquote><blockquote>home: MyHomePage(),</blockquote><blockquote>),</blockquote><blockquote>);</blockquote><blockquote>}</blockquote><blockquote>}</blockquote><blockquote>class MyHomePage extends StatelessWidget {</blockquote><blockquote>@override</blockquote><blockquote>Widget <em>build</em>(BuildContext context) {</blockquote><blockquote>return Scaffold(</blockquote><blockquote>appBar: AppBar(</blockquote><blockquote>centerTitle: true,</blockquote><blockquote>title: Text(‘Simple Counter Application’),</blockquote><blockquote>),</blockquote><blockquote>body: Center(</blockquote><blockquote>child: Column(</blockquote><blockquote>mainAxisAlignment: MainAxisAlignment.center,</blockquote><blockquote>children: &lt;Widget&gt;[</blockquote><blockquote>Text(</blockquote><blockquote>‘You have pushed the button this many times:’,</blockquote><blockquote>),</blockquote><blockquote>Consumer(</blockquote><blockquote>builder: (builder, counter, child) {</blockquote><blockquote>final count = <em>counter</em>(counterProvider);</blockquote><blockquote>return Text(count.counter.<em>toString</em>(),</blockquote><blockquote>style: Theme.<em>of</em>(context).textTheme.headline4);</blockquote><blockquote>},</blockquote><blockquote>),</blockquote><blockquote>SizedBox(</blockquote><blockquote>height: 20,</blockquote><blockquote>),</blockquote><blockquote>Row(</blockquote><blockquote>mainAxisAlignment: MainAxisAlignment.center,</blockquote><blockquote>children: [</blockquote><blockquote>FloatingActionButton(</blockquote><blockquote>onPressed: () {</blockquote><blockquote>context.<em>read</em>(counterProvider).<em>increment</em>();</blockquote><blockquote>},</blockquote><blockquote>tooltip: ‘Increment’,</blockquote><blockquote>child: Icon(Icons.exposure_plus_1),</blockquote><blockquote>),</blockquote><blockquote>SizedBox(</blockquote><blockquote>width: 20,</blockquote><blockquote>),</blockquote><blockquote>FloatingActionButton(</blockquote><blockquote>onPressed: () {</blockquote><blockquote>context.<em>read</em>(counterProvider).<em>decrement</em>();</blockquote><blockquote>},</blockquote><blockquote>tooltip: ‘Decrement’,</blockquote><blockquote>child: Icon(Icons.exposure_minus_1),</blockquote><blockquote>),</blockquote><blockquote>],</blockquote><blockquote>)</blockquote><blockquote>],</blockquote><blockquote>),</blockquote><blockquote>),</blockquote><blockquote>);</blockquote><blockquote>}</blockquote><blockquote>}</blockquote><p>So we have done it, We added Riverpod to the oldskool counter application and modified that into a modern counter application.</p><p>That’s it, for now, we will meet in the next blog. Bye Bye…..</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*98rMg3QH0CFXOEUVLN3GjQ.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8d246f6b5bfb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Evolution of Counter App Using Provider in Flutters]]></title>
            <link>https://boringdeveloper.medium.com/the-evolution-of-counter-app-using-provider-in-flutters-83e94589c1e7?source=rss-aa3473496e9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/83e94589c1e7</guid>
            <category><![CDATA[provider-flutter-app]]></category>
            <category><![CDATA[counter-app-provider]]></category>
            <category><![CDATA[provider-package-flutter]]></category>
            <category><![CDATA[app-using-provider]]></category>
            <dc:creator><![CDATA[Boring Developer]]></dc:creator>
            <pubDate>Mon, 16 Aug 2021 13:09:16 GMT</pubDate>
            <atom:updated>2021-08-16T13:09:16.287Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>Flutter</strong> is <strong>Google’s UI toolkit</strong> for making applications for mobile, web, and desktop platforms from a single codebase.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*LRmYpvJyn2bqZVwP0TLYpA.png" /><figcaption>Flutter Logo</figcaption></figure><p>Flutter was unveiled at the 2015 Dart developer summit with the stated intent of being able to <a href="https://en.wikipedia.org/wiki/Rendering_(computer_graphics)">r</a>ender consistently at 120 <a href="https://en.wikipedia.org/wiki/Frame_rate">f</a>ps. During the keynote of Google Developer Days in Shanghai, Google announced Flutter Release Preview 2, which is the last big release before Flutter 1.0. On December 4, 2018, Flutter 1.0 was released at the Flutter Live event, denoting the first “stable” version of the Framework.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/878/1*oFEZos1nwqTh16cEeL0Nzw.jpeg" /><figcaption>Install Flutter</figcaption></figure><p><strong>Flutter </strong>can be downloaded from <a href="http://flutter.dev">flutter. dev</a> and installed by following simple steps provided at the website or you can also install it (if on windows) by watching this video =&gt; <a href="https://www.youtube.com/watch?v=5Ga1cLW2S-U">https://www.youtube.com/watch?v=5Ga1cLW2S-U</a></p><p>So! Let’s Get onto our topic!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*4Hs_Q6RuBurX221zoH7Q2A.jpeg" /></figure><p>Flutter provides a simple counter application whenever you execute the below command for creating a new project with flutter</p><blockquote>flutter create projectname</blockquote><p>Our today’s task will be to use the provider package inside of this pre-created counter application. Hence, first of all, we will have to add the provider package in our pubspec.YAML file like this</p><blockquote>provider : ^5.0.0</blockquote><p>After adding the provider package to our pubspec.YAML let’s get onto our main. dart file and cook some code.</p><p>First of let’s edit the MyApp class of the pre-created counter application.</p><p>We first add our whole MaterialApp inside a ChangeNotifierProvider which will listen to our counter value. Then let’s quickly remove the title variable inside MyHomePage class and also because now we have immortal powers of the provider package let’s convert that class from StatefulWidget to StatelessWidget. It will look like this</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z_9SPhaBnrQT5cK4ogeh9A.jpeg" /><figcaption>We’ve got the immortal power of the provider package in our hands</figcaption></figure><blockquote>class MyApp extends StatelessWidget {</blockquote><blockquote>@override</blockquote><blockquote>Widget <em>build</em>(BuildContext context) {</blockquote><blockquote>return ChangeNotifierProvider(</blockquote><blockquote>create: (_) =&gt; CounterValue(),</blockquote><blockquote>child: MaterialApp(</blockquote><blockquote>title: ‘Flutter Demo’,</blockquote><blockquote>theme: ThemeData(</blockquote><blockquote>primarySwatch: Colors.blue,</blockquote><blockquote>),</blockquote><blockquote>home: MyHomePage(),</blockquote><blockquote>),</blockquote><blockquote>);</blockquote><blockquote>}</blockquote><blockquote>}</blockquote><p>And after that let’s create a new file named counterValue.dart which will have our counter variable and two very special increment and decrement functions using which we will increment and decrement values of our counter variable. This file will have a CounterValue class which will extend ChangeNotifier so that we can notify our listeners about the changes happening to the value of the counter variable. So this is what our CounterValue class will look like</p><blockquote>class CounterValue extends ChangeNotifier {</blockquote><blockquote>int counter = 0;</blockquote><blockquote>int get <em>getCounterValue</em> =&gt; counter;</blockquote><blockquote>void <em>increment</em>() {</blockquote><blockquote>counter += 1;</blockquote><blockquote><em>notifyListeners</em>();</blockquote><blockquote>}</blockquote><blockquote>void <em>decrement</em>() {</blockquote><blockquote>counter -= 1;</blockquote><blockquote><em>notifyListeners</em>();</blockquote><blockquote>}</blockquote><blockquote>}</blockquote><p>So that’s it, Now let’s use this variable value as well as both functions to complete our version of the counter application. First thing first let’s add two buttons, one for incrementing counter value and the second for decrementing the same. Next, let’s move on to our MyHomePage class which will have a text widget that will show the current value of the counter hence, let’s put it inside a Consumer of type CounterValue so that it can consume our counter value from CounterValue class we’ve just made. Also, we will make a final variable called counterProvider that will be equal to</p><blockquote>final counterProvider = Provider.<em>of</em>&lt;CounterValue&gt;(context, listen: false);</blockquote><p>And After that, we are ready to rock with this MyHomePage class</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/180/1*QgufMXOQDOy2TrGCevRanw.jpeg" /><figcaption>Let’s Rock</figcaption></figure><blockquote>class MyHomePage extends StatelessWidget {</blockquote><blockquote>@override</blockquote><blockquote>Widget <em>build</em>(BuildContext context) {</blockquote><blockquote>final counterProvider = Provider.<em>of</em>&lt;CounterValue&gt;(context, listen: false);</blockquote><blockquote>return Scaffold(</blockquote><blockquote>appBar: AppBar(</blockquote><blockquote>title: Text(‘Provider’),</blockquote><blockquote>),</blockquote><blockquote>body: Center(</blockquote><blockquote>child: Column(</blockquote><blockquote>mainAxisAlignment: MainAxisAlignment.center,</blockquote><blockquote>children: &lt;Widget&gt;[</blockquote><blockquote>Text(</blockquote><blockquote>‘You have pushed the button this many times:’,</blockquote><blockquote>),</blockquote><blockquote>Consumer&lt;CounterValue&gt;(</blockquote><blockquote>builder: (context, data, child) {</blockquote><blockquote>return Text(‘${data.counter}’,</blockquote><blockquote>style: Theme.<em>of</em>(context).textTheme.headline4);</blockquote><blockquote>},</blockquote><blockquote>),</blockquote><blockquote>SizedBox(</blockquote><blockquote>height: 20,</blockquote><blockquote>),</blockquote><blockquote>Row(</blockquote><blockquote>mainAxisAlignment: MainAxisAlignment.center,</blockquote><blockquote>children: [</blockquote><blockquote>FloatingActionButton(</blockquote><blockquote>onPressed: () {</blockquote><blockquote>counterProvider.<em>increment</em>();</blockquote><blockquote>},</blockquote><blockquote>tooltip: ‘Increment’,</blockquote><blockquote>child: Icon(Icons.exposure_plus_1),</blockquote><blockquote>),</blockquote><blockquote>SizedBox(</blockquote><blockquote>width: 20,</blockquote><blockquote>),</blockquote><blockquote>FloatingActionButton(</blockquote><blockquote>onPressed: () {</blockquote><blockquote>counterProvider.<em>decrement</em>();</blockquote><blockquote>},</blockquote><blockquote>tooltip: ‘Decrement’,</blockquote><blockquote>child: Icon(Icons.exposure_minus_1),</blockquote><blockquote>),</blockquote><blockquote>],</blockquote><blockquote>)</blockquote><blockquote>],</blockquote><blockquote>),</blockquote><blockquote>),</blockquote><blockquote><em>// This trailing comma makes auto-formatting nicer for build methods.</em></blockquote><blockquote>);</blockquote><blockquote>}</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/653/1*c278z9vWasCjCguhEBnxtA.png" /></figure><p>So that’s it we are done with adding provider to flutter’s pre-created counter application. We have added more functionalities to it by giving it the powers to increment and decrement the counter value with the help of our new and loyal friend <strong>Provider.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Vl5_l4QMgUoAkD1vvgKUVQ.jpeg" /></figure><blockquote><strong>Last but not the least Don’t forget to like, share and follow.</strong></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=83e94589c1e7" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>