<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Priya</title>
    <description>The latest articles on DEV Community by Priya (@priya01).</description>
    <link>https://dev.to/priya01</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1976205%2F2abf8503-e2ac-489f-87f3-018053b825f0.png</url>
      <title>DEV Community: Priya</title>
      <link>https://dev.to/priya01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/priya01"/>
    <language>en</language>
    <item>
      <title>Breaking Down the Cloud: A Simple Guide for Beginners</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Sun, 14 Dec 2025 07:56:35 +0000</pubDate>
      <link>https://dev.to/priya01/cloud-basics-explained-simply-50fh</link>
      <guid>https://dev.to/priya01/cloud-basics-explained-simply-50fh</guid>
      <description>&lt;p&gt;I recently started learning DevOps and cloud computing, and one thing I realized very quickly is that &lt;em&gt;cloud basics sound complicated&lt;/em&gt; — until you explain them simply.&lt;/p&gt;

&lt;p&gt;This post is part of a beginner-friendly series where I share what I’m learning as I go. No expert talk, no buzzwords — just practical understanding from someone who’s getting started.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Cloud Actually Means
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpooh0qthfcno9uohe0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpooh0qthfcno9uohe0w.png" alt="Cloud" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At its core, cloud computing means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;On-demand delivery of IT resources over the internet with pay-as-you-go pricing.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s break that down in simple terms.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 On-demand delivery
&lt;/h3&gt;

&lt;p&gt;You get resources &lt;strong&gt;when you need them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You don’t have to plan months ahead or buy hardware upfront. If you need a server right now, you can create one in minutes. If you don’t need it anymore, you can delete it.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 IT resources
&lt;/h3&gt;

&lt;p&gt;These are the building blocks you usually need to run applications, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Servers (virtual machines)&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Networking components (load balancers, firewalls, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of owning these physically, you rent them from a cloud provider.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Over the internet
&lt;/h3&gt;

&lt;p&gt;Cloud resources are accessed over the internet.&lt;/p&gt;

&lt;p&gt;As long as you have an internet connection, you can manage your infrastructure from anywhere in the world.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Pay-as-you-go pricing
&lt;/h3&gt;

&lt;p&gt;You &lt;strong&gt;pay only for what you use&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If a server runs for one hour, you pay for one hour. If it’s stopped, you usually don’t pay for compute anymore. This flexibility is powerful — but it also means you need to be careful with unused resources.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are virtual machines?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2yrlpsis9pdnrug8rz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2yrlpsis9pdnrug8rz1.png" alt="Virtualization" width="800" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;VMs provide flexibility, and are foundational to cloud computing, enabling multiple virtual servers on single hardware. &lt;/p&gt;

&lt;p&gt;A virtual machine (VM) is a software-based computer that runs inside a physical computer (the "host"), allowing you to run an entire operating system (like Windows on a Mac, or Linux on Windows) and its applications in an isolated environment, using a portion of the host's hardware resources (CPU, RAM, storage). &lt;/p&gt;

&lt;p&gt;If you have a powerful server, you wouldn’t want to dedicate it to just one OS. Virtualization allows you to split that server’s resources to run multiple VMs, each with its own operating system, efficiently using the hardware.&lt;/p&gt;




&lt;h2&gt;
  
  
  Types of Cloud Services
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjc0r1fiasfghssinpdf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjc0r1fiasfghssinpdf.jpg" alt="TYPES OF CLOUD SERVICES" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cloud services are generally divided into three models, based on what the provider manages versus what the user controls:&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 IaaS (Infrastructure as a Service)
&lt;/h3&gt;

&lt;p&gt;IaaS provides virtualized computing resources over the internet. You rent servers, storage, and networks, but you manage the operating system and applications yourself.&lt;/p&gt;

&lt;p&gt;Examples: AWS, GCP, Azure&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 PaaS (Platform as a Service)
&lt;/h3&gt;

&lt;p&gt;PaaS provides a platform for developing and running applications without managing the underlying servers, storage, or networking — the provider takes care of the infrastructure.&lt;/p&gt;

&lt;p&gt;Examples: Heroku, Google App Engine&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 SaaS (Software as a Service)
&lt;/h3&gt;

&lt;p&gt;SaaS delivers fully managed software applications over the cloud. You use the software without worrying about infrastructure or platform management.&lt;/p&gt;

&lt;p&gt;Examples: Gmail, Dropbox, Slack&lt;/p&gt;




&lt;h2&gt;
  
  
  Why you can try it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkr69d4c3sr5ritqfi6rk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkr69d4c3sr5ritqfi6rk.png" alt="Benefits" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flexible, pay-as-you-go costs instead of fixed expenses. &lt;/li&gt;
&lt;li&gt;Lower maintenance and running costs compared to owning hardware.&lt;/li&gt;
&lt;li&gt;Scale capacity up or down without worrying about servers.&lt;/li&gt;
&lt;li&gt;Elasticity — automatically scale resources up or down to meet changing demand.&lt;/li&gt;
&lt;li&gt;Agility — quickly allocate resources, adapt to changing workloads, and rapidly test &amp;amp; deploy applications.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;Cloud computing might seem complex at first, but breaking it down into simple concepts like on-demand resources, virtualization, and benefits makes it much easier to understand.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cloud</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Fixing ChatGPT’s Hidden Edit Button – A Reminder That Testing Matters!</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Sat, 15 Feb 2025 11:01:57 +0000</pubDate>
      <link>https://dev.to/priya01/fixing-chatgpts-hidden-edit-button-a-reminder-that-testing-matters-1me4</link>
      <guid>https://dev.to/priya01/fixing-chatgpts-hidden-edit-button-a-reminder-that-testing-matters-1me4</guid>
      <description>&lt;p&gt;Today, I ran into a strange issue—&lt;strong&gt;I couldn’t edit my messages in ChatGPT!&lt;/strong&gt; 🤔 At first, I thought it was a bug, but after some searching, I found the solution in a &lt;a href="https://community.openai.com/t/why-cant-edit-my-message-to-chat-gpt-anymore/1120919/23" rel="noopener noreferrer"&gt;forum thread&lt;/a&gt;.  &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;The Issue?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The edit button wasn’t removed—it was just &lt;strong&gt;hidden using &lt;code&gt;display: none;&lt;/code&gt; in CSS!&lt;/strong&gt; Maybe this happened after they added a certain feature and forgot to re-enable it?&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;The Fix?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I followed the forum’s suggestion:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;DevTools&lt;/strong&gt; (Right-click → Inspect or press &lt;code&gt;F12&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Find the edit button’s HTML.
&lt;/li&gt;
&lt;li&gt;Remove &lt;code&gt;display: none;&lt;/code&gt; from its styles.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And boom—the edit button was back! 🎉  &lt;/p&gt;

&lt;p&gt;Before...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbw868v6w0viszf74k5pz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbw868v6w0viszf74k5pz.png" alt="before" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe4ywtv78k4avwmbxkoh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe4ywtv78k4avwmbxkoh6.png" alt="after" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep in mind, this fix only works until you refresh the page. A permanent fix would require changes from OpenAI’s side.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;em&gt;Turns out, the edit button was just playing hide and seek behind display: none; 😆&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Why This Matters – The Importance of Testing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This small UI issue is a great example of why &lt;strong&gt;testing is crucial, even for well-established products.&lt;/strong&gt; A simple CSS rule change can unintentionally break core functionality. &lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;UI testing&lt;/strong&gt; could have caught this before release.&lt;br&gt;&lt;br&gt;
🔹 &lt;strong&gt;Regression testing&lt;/strong&gt; might have flagged the missing edit button.&lt;br&gt;&lt;br&gt;
🔹 &lt;strong&gt;User feedback&lt;/strong&gt; helped surface the issue, but it’s always better to catch it earlier!  &lt;/p&gt;

&lt;p&gt;Even big companies can have small oversights, and this is why thorough testing matters—whether you're working on a personal project or a large-scale application.  &lt;/p&gt;

&lt;p&gt;Have you ever fixed a UI bug like this? Share your experience in the comments!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>chatgpt</category>
      <category>css</category>
      <category>testing</category>
    </item>
    <item>
      <title>Wait... Should We Be Doing It This Way?</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Fri, 07 Feb 2025 17:28:32 +0000</pubDate>
      <link>https://dev.to/priya01/wait-should-we-be-doing-it-this-way-3jpj</link>
      <guid>https://dev.to/priya01/wait-should-we-be-doing-it-this-way-3jpj</guid>
      <description>&lt;p&gt;Every developer has that moment when they stumble upon something in their codebase that makes them pause and think: “Wait... should we really be doing it this way?” Recently, I had a few of those moments, and they sparked some learning opportunities.&lt;/p&gt;

&lt;p&gt;From unconventional API endpoint names to sending plaintext passwords over HTTPS, and even battling XSS attacks, it’s been a series of challenges. Let me take you on this journey!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78zvj3pt7076g1z6vp21.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78zvj3pt7076g1z6vp21.gif" alt="Coding gif" width="400" height="225"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. API Naming 🔍
&lt;/h2&gt;

&lt;p&gt;Imagine you’re the new developer on the team, and you see API endpoints named &lt;code&gt;get_accounts&lt;/code&gt; or &lt;code&gt;remove_folders&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functional? Yes. Elegant? Not so much.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s like calling a restaurant menu item “Fetch_Burger” instead of just “Burger🍔"&lt;/p&gt;

&lt;h4&gt;
  
  
  What’s the Problem?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;It’s not RESTful. REST APIs are meant to be clean and resource-oriented, not action-packed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action vs. Resource&lt;/strong&gt;: RESTful API design focuses on resources rather than actions. Think of an action like &lt;code&gt;get&lt;/code&gt; or &lt;code&gt;remove&lt;/code&gt; as something that should be implied by the HTTP verb, not included in the URL.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The Fix:
&lt;/h4&gt;

&lt;p&gt;Let the HTTP methods do the heavy lifting!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /accounts&lt;/code&gt; instead of &lt;code&gt;GET /get_accounts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DELETE /folders/{folder_id}&lt;/code&gt; instead of &lt;code&gt;DELETE /remove_folders/{folder_id}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, it’s like having a clean, organized menu where you know exactly what to expect.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. DOM Manipulation in Ember.js 🔧
&lt;/h2&gt;

&lt;p&gt;I stumbled upon some .js files where the DOM was being accessed directly, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#my-element&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This felt like bypassing a chef in a fancy restaurant to cook your own food in their kitchen—messy, unnecessary, and against the rules😒.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why This Matters:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Ember.js is built to handle the DOM for you. Manual manipulation can break reactivity and create inconsistencies.&lt;/li&gt;
&lt;li&gt;It also has powerful tools like &lt;strong&gt;tracked properties and services&lt;/strong&gt; that help manage state without directly manipulating the DOM. By embracing this, you make your components more maintainable and avoid potential issues with synchronization between the UI and underlying state.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The Fix:
&lt;/h4&gt;

&lt;p&gt;Let Ember do the heavy lifting with its reactive template system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;greeting&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need to interact with the DOM? Use lifecycle hooks. This keeps your code elegant, predictable, and future-proof.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Passwords Over HTTPS 🔐
&lt;/h2&gt;

&lt;p&gt;Is it ok to send plaintext passwords over HTTPS? Yes, HTTPS encrypts traffic, but it’s like locking your front door while leaving your house key under the mat—it’s still a bad idea🫤.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why It’s Risky:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Logs or intermediaries might capture plaintext passwords.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The Fix:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Handle passwords securely on the server.&lt;/li&gt;
&lt;li&gt;Instead of storing passwords as plaintext, hash them using algorithms like &lt;strong&gt;bcrypt&lt;/strong&gt;, or &lt;strong&gt;scrypt&lt;/strong&gt; with a unique salt for each password.&lt;/li&gt;
&lt;li&gt;Consider token-based authentication systems (like JWTs) to replace raw password handling altogether.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want to dive deeper into JWTs and why they're a game-changer for secure authentication? Check out &lt;a href="https://dev.to/priya01/jwts-the-secret-code-for-web-security-22k"&gt;this post&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. XSS Attacks🛡️
&lt;/h2&gt;

&lt;p&gt;This one felt like a mini-war. We recently discovered XSS vulnerabilities in the codebase—where attackers could inject malicious scripts into our web pages. It was like realizing you’ve left your windows open during a storm💨.&lt;/p&gt;

&lt;p&gt;Get a clear understanding of XSS 🤏 &lt;a href="https://hacksplaining.com/lessons/xss-stored" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Risks:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Attackers can steal data, hijack sessions, or run unauthorized scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How We Fought Back:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Input Sanitization: We made sure all user inputs are cleaned up before rendering.&lt;/li&gt;
&lt;li&gt;Content Security Policy (CSP): Strengthened our CSP to block unauthorized scripts.&lt;/li&gt;
&lt;li&gt;Output Escaping: Leveraged Ember’s built-in escaping mechanisms to prevent scripts from running in templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, the codebase feels like a fortress—not impenetrable, but definitely harder to breach.&lt;/p&gt;

&lt;p&gt;Not familiar with Content Security Policy (CSP)? Check out &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP" rel="noopener noreferrer"&gt;this guide on MDN&lt;/a&gt; to learn how it strengthens web security.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrap-Up
&lt;/h2&gt;

&lt;p&gt;Codebases grow, evolve, and sometimes pick up bad habits along the way. The key is to keep learning and improving. If you’ve ever had similar “aha!” moments in your codebase, I’d love to hear your stories. &lt;em&gt;After all, every bug fixed is a lesson learned!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Happy Coding 💻&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>coding</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Django + Redis: Simplifying Data Caching with a Real-World Example</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Sun, 02 Feb 2025 08:01:27 +0000</pubDate>
      <link>https://dev.to/priya01/django-redis-simplifying-data-caching-with-a-real-world-example-4nnn</link>
      <guid>https://dev.to/priya01/django-redis-simplifying-data-caching-with-a-real-world-example-4nnn</guid>
      <description>&lt;p&gt;In the previous post, we discussed the basics of Redis and its key use cases. I hope you're now familiar with what Redis is and how it can be helpful in various scenarios. As promised, today we'll explore a real-world example of how to implement Redis in a Django application for a ticketing system. &lt;/p&gt;

&lt;h2&gt;
  
  
  Use Case: High-Demand Ticketing System
&lt;/h2&gt;

&lt;p&gt;Imagine you're building a ticketing system where users can book tickets for events like concerts or flights. Let's say we have a high demand of booking, how can we make sure that no two person's are booking the same ticket. &lt;/p&gt;

&lt;p&gt;In most ticketing systems, when you try to book a ticket, you are given a specific window of time (e.g., 5 minutes) in which the ticket is reserved for you. During this time, the ticket is neither available for other users nor confirmed as booked yet. If another user visits the booking page, they should see that the ticket is already reserved, not available.&lt;/p&gt;

&lt;p&gt;Now, let's think about how we can handle this in real time. Should we store the reservation in the database for 5 minutes to mark the ticket as "reserved"? While this might work, there are a couple of issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Database Overhead&lt;/strong&gt;: Continuously writing and updating the database for every reservation request may not be optimal, especially if the system has a high volume of users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Handling Expiry&lt;/strong&gt;: After 5 minutes, we need to automatically reset the ticket status back to "Available" if it's not booked. Setting up a cron job to check and update ticket statuses might be one solution, but it's a bit of an overkill and introduces complexity.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How Redis Solves This Problem
&lt;/h2&gt;

&lt;p&gt;Redis, with its ability to handle high-frequency reads and writes in real-time, can help solve both of these problems efficiently. Redis provides a feature called &lt;strong&gt;TTL (Time-To-Live)&lt;/strong&gt;, which automatically expires keys after a set duration.&lt;/p&gt;

&lt;p&gt;Here's how Redis can work for our ticketing system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a user reserves a ticket, we store the reservation in Redis with a &lt;strong&gt;TTL of 5 minutes&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If the reservation is not confirmed within that time, Redis will automatically delete the key, making the ticket available again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the flow,&lt;/p&gt;

&lt;p&gt;When user needs to book a ticket, we get all the available tickets (not booked) and took all the tickets (may be, ticketId) from Redis and show this accordingly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0256ljeuqws2egmsyav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0256ljeuqws2egmsyav.png" alt="Redis flow" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This way, we don't need to constantly update the database. Redis acts as a high-performance, low-latency cache for ticket reservations.&lt;/p&gt;

&lt;p&gt;But, what happens if two users try to reserve the same ticket at the same time? 🤔&lt;/p&gt;

&lt;p&gt;The answer is that Redis guarantees atomic operations. This means that if two users attempt to reserve the same ticket simultaneously, Redis will ensure that only one succeeds, preventing both users from booking the same ticket. &lt;/p&gt;




&lt;h2&gt;
  
  
  Setting Up Redis in Django
&lt;/h2&gt;

&lt;p&gt;Before diving into the implementation, ensure you've set up Redis in your Django project. You can follow this excellent &lt;a href="https://medium.com/django-unleashed/caching-in-django-with-redis-a-step-by-step-guide-40e116cb4540" rel="noopener noreferrer"&gt;tutorial on caching in Django with Redis&lt;/a&gt; by Mehedi Khan to configure Redis as your cache backend.&lt;/p&gt;

&lt;p&gt;Once Redis is up and running in your project, we'll proceed with implementing the ticket reservation logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementing Ticket Reservation Logic
&lt;/h2&gt;

&lt;p&gt;Assuming you've set up Redis, let's implement the core logic for reserving tickets.&lt;/p&gt;

&lt;p&gt;First, let's define the &lt;code&gt;Ticket&lt;/code&gt; model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Ticket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;STATUS_CHOICES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;available&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Available&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;booked&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Booked&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DecimalField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_digits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;decimal_places&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                              &lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;STATUS_CHOICES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;available&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Add more fields as necessary...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a user tries to book a ticket, we need to reserve it for them in Redis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.core.cache&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Ticket&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reserve_ticket_in_redis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;reservation_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ticket_reservation_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticket_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="c1"&gt;# Check if the ticket is already reserved
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reservation_key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="c1"&gt;# If not reserved, set the reservation key with TTL
&lt;/span&gt;    &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reservation_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reserved&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;book_ticket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ticket_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ticket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ticket_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Check if the ticket is already booked in the database
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;booked&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sorry, this ticket is already booked.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Attempt to reserve the ticket in Redis
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;reserve_ticket_in_redis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This ticket is already reserved by another user. Please try again later.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ticket reserved successfully for 5 minutes. Please complete your booking.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When users view a particular event, we need to show them a list of available tickets that are neither booked nor reserved. We can check both the ticket status and Redis cache for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.core.cache&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_object_or_404&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;event_details&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_object_or_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;all_tickets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tickets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;available_tickets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ticket&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;all_tickets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Skip tickets that are booked or reserved in Redis
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;booked&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ticket_reservation_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;  &lt;span class="c1"&gt;# Don't show this ticket to the user
&lt;/span&gt;
        &lt;span class="c1"&gt;# Add ticket to available list if not booked or reserved
&lt;/span&gt;        &lt;span class="n"&gt;available_tickets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;event_details.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;event&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;available_tickets&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;available_tickets&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Redis Reservation: The &lt;code&gt;reserve_ticket_in_redis&lt;/code&gt; function attempts to reserve the ticket in Redis using &lt;code&gt;cache.set()&lt;/code&gt; and &lt;code&gt;cache.get()&lt;/code&gt;, which ensures the key is only set if it doesn't already exist. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Atomic Operations: This ensures that if two users try to reserve the same ticket at the same time, only one will succeed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;In this post, we’ve explored how Redis can be used in a Django ticketing system to manage ticket reservations efficiently. By utilizing Redis’ &lt;strong&gt;TTL&lt;/strong&gt; feature, we can reserve tickets for a set period (e.g., 5 minutes), and automatically make them available again if not confirmed. This reduces the load on the database and avoids race conditions by ensuring atomic operations for concurrent reservations.&lt;/p&gt;

&lt;p&gt;Let me know if you have any questions or need further clarification!&lt;/p&gt;

&lt;p&gt;Happy Designing! 😊💻&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>redis</category>
      <category>learning</category>
    </item>
    <item>
      <title>Redis Demystified: A Simple Introduction for System Design</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Sun, 26 Jan 2025 09:55:06 +0000</pubDate>
      <link>https://dev.to/priya01/redis-demystified-a-simple-introduction-for-system-design-56mb</link>
      <guid>https://dev.to/priya01/redis-demystified-a-simple-introduction-for-system-design-56mb</guid>
      <description>&lt;p&gt;You’ve probably encountered the word "Redis" many times while learning about system design. This tutorial will give you a better understanding (I hope) of what Redis is all about from a beginner's perspective, and in the future, we'll dive deeper into real-world examples of how to implement Redis in your applications.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwzxqa5bgduaafw43tj8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwzxqa5bgduaafw43tj8.gif" alt="Redis Image" width="256" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redis is a single-threaded, in-memory data structure server or data store. It’s incredibly fast compared to traditional databases because it operates in &lt;strong&gt;memory (RAM)&lt;/strong&gt; instead of &lt;strong&gt;disk storage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So many terms? No worries! Let’s break it down and understand each one:&lt;/p&gt;




&lt;h3&gt;
  
  
  Single Threaded
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tp0lki4k4b1jq4m1q3f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tp0lki4k4b1jq4m1q3f.png" alt="Single thread" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redis processes all requests on a single thread. While this might seem like a bottleneck, it’s actually a well-thought-out design choice that ensures simplicity and efficiency. Redis achieves this efficiency using a mechanism called &lt;strong&gt;I/O Multiplexing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understanding I/O Multiplexing with an Analogy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine a waiter in a busy restaurant where customers are lining up to place their orders. If the waiter attends to one customer at a time—waiting for them to browse the menu and decide what to order—other customers would have to wait longer.&lt;/p&gt;

&lt;p&gt;Now, let’s make an improvement: The waiter places menus at each table so customers can decide on their orders in advance. Instead of waiting for each customer to be ready, the waiter immediately takes orders from those who are prepared, significantly reducing waiting time.&lt;/p&gt;

&lt;p&gt;This is similar to how I/O Multiplexing works in Redis.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Redis server listens to all incoming requests.&lt;/li&gt;
&lt;li&gt;Some clients may be idle (e.g., not sending commands).&lt;/li&gt;
&lt;li&gt;Redis processes the requests that are ready to be handled, ensuring smooth and fast operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By doing this, Redis optimizes performance and keeps things simple without needing multiple threads or complex locking mechanisms.&lt;/p&gt;




&lt;h3&gt;
  
  
  In-Memory
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zffvmp8dwuo3qt4p7tl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zffvmp8dwuo3qt4p7tl.png" alt="Im-memory db image" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redis is an &lt;strong&gt;in-memory&lt;/strong&gt; data store, meaning it keeps all its data in &lt;strong&gt;RAM&lt;/strong&gt; for fast access. This in-memory design allows Redis to be incredibly fast for read and write operations, as accessing data from RAM is much quicker than from disk storage.  &lt;/p&gt;

&lt;p&gt;However, because RAM is volatile, meaning the data is lost if the server crashes, Redis provides mechanisms to ensure that data persists even in case of unexpected failures. Redis periodically saves its data to disk using two mechanisms:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Snapshotting&lt;/strong&gt;: Redis saves the dataset to disk at specified intervals, creating a point-in-time snapshot of the data. By default, Redis writes this snapshot to disk:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Every 900 seconds (15 minutes)&lt;/strong&gt; if at least one key has changed.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every 300 seconds (5 minutes)&lt;/strong&gt; if at least 100 keys have changed.
(This data was gathered from sources like Google, but it's always good to double-check against Redis documentation for accuracy.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Append-Only File (AOF)&lt;/strong&gt;: Redis can also log every write operation to an append-only file, allowing the data to be reconstructed in case of a crash.  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These settings are configurable, meaning you can adjust how often Redis saves data to disk based on your application’s needs.&lt;/p&gt;




&lt;h3&gt;
  
  
  Data structure
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqqg09qn7aftwxq11ulx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqqg09qn7aftwxq11ulx.png" alt="Data structures image" width="788" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We often learn more about &lt;strong&gt;Data Structures and Algorithms (DSA)&lt;/strong&gt; than other topics in computer science, but why focus on &lt;strong&gt;Data Structures&lt;/strong&gt; here? Redis allows you to store data as &lt;strong&gt;key-value pairs&lt;/strong&gt;, where the value can be a variety of data structures, from simple &lt;strong&gt;strings&lt;/strong&gt; and &lt;strong&gt;integers&lt;/strong&gt; to more complex ones like &lt;strong&gt;Lists&lt;/strong&gt;, &lt;strong&gt;Sets&lt;/strong&gt;, &lt;strong&gt;Sorted Sets&lt;/strong&gt;, and even &lt;strong&gt;Hashes&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;This flexibility in data structures is one of the reasons Redis is so powerful. It allows you to efficiently handle and manipulate different types of data based on your needs. &lt;/p&gt;




&lt;h2&gt;
  
  
  Commands to Start Off With
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SET: Set a value for a key.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SET mykey &lt;span class="s2"&gt;"Hello, World!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GET: Retrieve the value of a key.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GET mykey
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;DEL: Delete a key.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;DEL mykey
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;EXPIRE: Set an expiration time on a key.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;EXPIRE mykey 60  &lt;span class="c"&gt;# Key expires in 60 seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;HSET: Set a field in a hash (similar to object).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;HSET user:1000 name &lt;span class="s2"&gt;"Priya"&lt;/span&gt;
HSET user:1000 email &lt;span class="s2"&gt;"priya@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And much more! &lt;/p&gt;

&lt;p&gt;For a quick reference on Redis commands, check out the official &lt;a href="https://redis.io/learn/howtos/quick-start/cheat-sheet" rel="noopener noreferrer"&gt;Redis Quick Start Cheat Sheet&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Imagine you have a web application where users frequently query a product database. Repeated queries for the same product can be slow and waste resources. Here’s how Redis can help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set Product Data in Redis:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SET product:1234 &lt;span class="s2"&gt;"{ 'name': 'Laptop', 'price': 1000 }"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check Redis Before Querying Database:
Before hitting the database for a product, check Redis to see if the data exists.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GET product:1234
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use Expiration:
To avoid outdated data, set an expiration time on the cached data.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;EXPIRE product:1234 600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Wrap-Up
&lt;/h2&gt;

&lt;p&gt;Redis is a powerful tool that enables fast, flexible data management using in-memory storage. By understanding its core concepts, you can use Redis to improve your application’s performance and scalability.&lt;/p&gt;

&lt;p&gt;Feel free to share your experiences with Redis or any tips you have!&lt;/p&gt;

&lt;p&gt;Happy Designing! 😊💻&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>redis</category>
      <category>learning</category>
    </item>
    <item>
      <title>Understanding the CAP Theorem: Simplified</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Sun, 19 Jan 2025 06:19:28 +0000</pubDate>
      <link>https://dev.to/priya01/understanding-the-cap-theorem-simplified-54o0</link>
      <guid>https://dev.to/priya01/understanding-the-cap-theorem-simplified-54o0</guid>
      <description>&lt;p&gt;When discussing system design, the &lt;strong&gt;CAP theorem&lt;/strong&gt; is one of the most fundamental and frequently mentioned concepts. But what does it actually mean? Let’s break it down with a simple example.&lt;/p&gt;

&lt;h4&gt;
  
  
  Scenario: A Blog Website
&lt;/h4&gt;

&lt;p&gt;Imagine you’re running a blog website that serves a large user base. To efficiently handle the traffic, you deploy &lt;strong&gt;multiple servers&lt;/strong&gt;, with each server processing user requests. Additionally, you implement &lt;strong&gt;database redundancy&lt;/strong&gt; by creating multiple copies of your database that work with these servers. &lt;/p&gt;

&lt;p&gt;This setup provides two key advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fault Tolerance:&lt;/strong&gt; If the primary (master) database fails, secondary databases can take over, ensuring continuous service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Availability:&lt;/strong&gt; Redundant databases ensure users can access content even during server or database failures.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Primary-Secondary Database Architecture: A Quick Overview
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;primary-secondary architecture&lt;/strong&gt; (also called &lt;strong&gt;master-slave architecture&lt;/strong&gt;) is widely used in distributed systems. Here's how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;primary database&lt;/strong&gt; handles all write operations and replicates updates to secondary databases.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;secondary databases&lt;/strong&gt; handle read operations, improving system efficiency and fault tolerance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design supports high availability and resilience but comes with trade-offs, which the CAP theorem helps us understand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4485qbodivb95zgqubw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4485qbodivb95zgqubw.png" alt="Master-slave architecture" width="570" height="610"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The CAP Theorem
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;CAP theorem&lt;/strong&gt; highlights the trade-offs that distributed systems face by focusing on three essential properties:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consistency (C):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensures that all nodes in the system see the same data at the same time. &lt;/li&gt;
&lt;li&gt;Example: If a user updates a blog post, all servers must immediately reflect the updated content, ensuring no stale data is read.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Availability (A):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Guarantees that every request receives a response (read or write), even if the data is not the most recent.&lt;/li&gt;
&lt;li&gt;Example: Users can still view and interact with the website, even if some database nodes are experiencing issues.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Partition Tolerance (P):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensures the system continues to function despite network partitions or communication breakdowns between servers.&lt;/li&gt;
&lt;li&gt;Example: If servers cannot communicate due to network failure, the system still serves requests to the best of its ability.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  The Trade-offs: Which Two Should You Prioritize?
&lt;/h3&gt;

&lt;p&gt;The CAP theorem states that you can’t achieve all three properties at once. So, how do you prioritize?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Consistency and Availability (CA):&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This trade-off assumes no network partitions, which is rare in real-world distributed systems. If network partitions don’t occur, the system can maintain consistency and respond to all requests.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Consistency and Partition Tolerance (CP):&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When network partitions occur, prioritizing consistency means every read receives the most recent write. This may come at the cost of availability, as the system might reject requests if it cannot guarantee consistency.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Availability and Partition Tolerance (AP):&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In scenarios where uptime is critical, the system continues to serve requests even during network partitions. However, data may not always be consistent across nodes, leading to eventual consistency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lj1xhkls1racjkfptpb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lj1xhkls1racjkfptpb.png" alt="CAP" width="790" height="661"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Your Use Case: Which Trade-off to Choose?
&lt;/h3&gt;

&lt;p&gt;Think about the system you’re building. Here’s how to approach the trade-offs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose &lt;strong&gt;Consistency and Partition Tolerance (CP)&lt;/strong&gt; if data accuracy is critical (e.g., in financial applications).&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Availability and Partition Tolerance (AP)&lt;/strong&gt; if uptime and accessibility are your priorities (e.g., in social media platforms).&lt;/li&gt;
&lt;li&gt;In specific scenarios without network partitions, &lt;strong&gt;Consistency and Availability (CA)&lt;/strong&gt; might be possible, but this is rare.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  What about PACELC?
&lt;/h3&gt;

&lt;p&gt;The PACELC theorem extends CAP and adds another dimension:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During a Partition (P), prioritize either Availability (A) or Consistency (C) (as in CAP).&lt;/li&gt;
&lt;li&gt;Else (E), when there’s no partition, choose between Latency (L) and Consistency (C).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Latency vs Consistency: What’s the Right Balance?&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latency (L): Systems prioritize quick responses, even if the data might not be up-to-date.&lt;/li&gt;
&lt;li&gt;Consistency (C): Systems ensure that users always see the most accurate data, even if responses are slightly slower. &lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Wrap-Up
&lt;/h3&gt;

&lt;p&gt;Understanding the &lt;strong&gt;CAP&lt;/strong&gt; theorem and the &lt;strong&gt;PACELC&lt;/strong&gt; extension helps in designing systems that align with specific use cases. By balancing the trade-offs, you can design systems optimized for reliability, performance, and user experience.&lt;/p&gt;

&lt;p&gt;Have questions or suggestions? Drop them in the comments!&lt;/p&gt;

&lt;p&gt;Happy Designing! 💻😊&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>performance</category>
      <category>learning</category>
    </item>
    <item>
      <title>Kickstarting Weekly System Design Deep Dives: Building Scalable Systems</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Sun, 12 Jan 2025 11:25:37 +0000</pubDate>
      <link>https://dev.to/priya01/kickstarting-weekly-system-design-deep-dives-building-scalable-systems-43ob</link>
      <guid>https://dev.to/priya01/kickstarting-weekly-system-design-deep-dives-building-scalable-systems-43ob</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To truly master something, you must create an obligation to teach it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inspired by this idea, I’m launching this &lt;strong&gt;weekly series&lt;/strong&gt; to master system design and share my journey and insights with you.&lt;/p&gt;

&lt;p&gt;How do platforms like &lt;strong&gt;Netflix&lt;/strong&gt; and &lt;strong&gt;Amazon&lt;/strong&gt; handle millions of users daily without breaking a sweat? The answer lies in &lt;strong&gt;system design&lt;/strong&gt;—a crucial skill for building scalable and reliable systems.&lt;/p&gt;

&lt;p&gt;At its core, system design is about solving real-world challenges such as:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scaling systems to accommodate millions of users.
&lt;/li&gt;
&lt;li&gt;Ensuring high availability, even during failures.
&lt;/li&gt;
&lt;li&gt;Managing vast amounts of data efficiently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Take a URL shortener, for example. The system needs to ensure unique links, redirect users quickly, and scale seamlessly as traffic grows.&lt;/p&gt;

&lt;p&gt;Netflix, for instance, uses microservices to scale its platform, allowing it to handle millions of users and maintain high availability.&lt;/p&gt;

&lt;p&gt;If you’re just starting with system design, I highly recommend reading &lt;strong&gt;Designing Data-Intensive Applications by Martin Kleppmann&lt;/strong&gt; for deeper insights.&lt;/p&gt;

&lt;p&gt;Interested? Follow along for weekly posts on system design, and let’s learn together. Got questions or topics you’d like to explore? Drop them in the comments!🚀&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>performance</category>
      <category>learning</category>
    </item>
    <item>
      <title>Optimizing Query Performance in Django with PostgreSQL: A Case Study</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Sun, 29 Dec 2024 09:51:43 +0000</pubDate>
      <link>https://dev.to/priya01/optimizing-query-performance-in-django-with-postgresql-a-case-study-4om3</link>
      <guid>https://dev.to/priya01/optimizing-query-performance-in-django-with-postgresql-a-case-study-4om3</guid>
      <description>&lt;p&gt;Recently, I started working on a feature that required me to optimize the database queries being fired from the code I wrote. This optimization is critical for ensuring the home page loads quickly, providing a seamless user experience without delays.&lt;/p&gt;

&lt;p&gt;Let me give a short intro about the application I’m working with. It’s a &lt;strong&gt;Django&lt;/strong&gt; app with a &lt;strong&gt;PostgreSQL&lt;/strong&gt; database. The feature I’m working on involves logic that needs data from multiple models, as the application is well modularized.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More modularized? A problem!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We all tend to follow certain coding principles we’ve learned, one of which is writing modularized, reusable pieces of code. This approach is great for maintainability and scalability, but when it comes to database queries, it can sometimes lead to inefficiency.&lt;/p&gt;




&lt;h3&gt;
  
  
  Checking Query Execution Time in Django
&lt;/h3&gt;

&lt;p&gt;First, I thought of checking the performance of the queries that are being fired from my code. I got the raw SQL and then tried executing that in &lt;strong&gt;pgAdmin&lt;/strong&gt; and analyzed the results using &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt;. For example, If you want to analyze a query, prefix it with &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a snippet of how it looked when I used the &lt;code&gt;IN&lt;/code&gt; clause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="nv"&gt;"Unique  (cost=8.19..8.20 rows=1 width=16) (actual 
time=0.045..0.047 rows=1 loops=1)"&lt;/span&gt;
&lt;span class="nv"&gt;"  -&amp;gt;  Sort  (cost=8.19..8.20 rows=1 width=16) (actual 
time=0.045..0.045 rows=1 loops=1)"&lt;/span&gt;
&lt;span class="nv"&gt;"Planning Time: 0.229 ms"&lt;/span&gt;
&lt;span class="nv"&gt;"Execution Time: 0.076 ms"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I switched to using &lt;code&gt;JOIN&lt;/code&gt;, and here's the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="nv"&gt;"HashAggregate  (cost=30.07..32.69 rows=262 width=16) (actual 
time=0.148..0.150 rows=1 loops=1)"&lt;/span&gt;
&lt;span class="nv"&gt;"  Batches: 1  Memory Usage: 37kB"&lt;/span&gt;
&lt;span class="nv"&gt;"  -&amp;gt;  Nested Loop  (cost=4.21..28.76 rows=262 width=16) (actual
 time=0.119..0.140 rows=1 loops=1)"&lt;/span&gt;
&lt;span class="nv"&gt;"Planning Time: 0.455 ms"&lt;/span&gt;
&lt;span class="nv"&gt;"Execution Time: 0.222 ms"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Noted Anything???&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, the &lt;strong&gt;"Execution Time"&lt;/strong&gt;! &lt;/p&gt;

&lt;p&gt;It shows that using &lt;code&gt;IN&lt;/code&gt; is faster than using &lt;code&gt;JOIN&lt;/code&gt; for this specific case. However, there’s a key question we need to consider: Will this scale for larger datasets? What happens if the data inside the &lt;code&gt;IN&lt;/code&gt; clause is significantly larger? Will it still perform well? The answer to this is &lt;strong&gt;A Big No&lt;/strong&gt;. &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Performance Comparison&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To better understand the trade-offs between &lt;code&gt;IN&lt;/code&gt; and &lt;code&gt;JOIN&lt;/code&gt;, let’s analyze how the database handles these two approaches, especially as the dataset grows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using &lt;code&gt;IN&lt;/code&gt;&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;When using &lt;code&gt;IN&lt;/code&gt;, the database is essentially checking if each row in the main table exists in a list of values. While this can be fast for smaller datasets, as the list in the &lt;code&gt;IN&lt;/code&gt; clause grows, PostgreSQL has to scan a larger set of values. This leads to increased execution time and potentially a full table scan, especially if the subquery or list of values is large.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using &lt;code&gt;JOIN&lt;/code&gt;&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;On the other hand, &lt;code&gt;JOIN&lt;/code&gt; creates a relationship between tables based on matching values in the columns, allowing the database to optimize the process using indexes. Although the execution time may seem worse for small data sets (as we saw in our initial test), &lt;code&gt;JOIN&lt;/code&gt; performs much better when dealing with larger datasets.&lt;/p&gt;




&lt;h3&gt;
  
  
  What you can use?
&lt;/h3&gt;

&lt;p&gt;It depends! Yes, it depends on your use case and the problem you're trying to solve. It’s not always the case that you should use &lt;code&gt;JOIN&lt;/code&gt;—for smaller sets of data, &lt;code&gt;IN&lt;/code&gt; might be more efficient.&lt;/p&gt;

&lt;p&gt;So, have a good understanding of the use case and get insights from people who have a better understanding than you about it. If you feel like the data is going to be large and it will affect performance, you can definitely go for &lt;code&gt;JOIN&lt;/code&gt;. And yes, don't forget to create &lt;strong&gt;Indexes&lt;/strong&gt; on your database to make your &lt;code&gt;JOINS&lt;/code&gt; perform better.&lt;/p&gt;




&lt;h3&gt;
  
  
  Know Indexing better
&lt;/h3&gt;

&lt;p&gt;Indexes are critical when working with joins on large datasets. They allow PostgreSQL to quickly locate rows based on indexed columns, significantly speeding up the query performance. To optimize your &lt;code&gt;JOIN&lt;/code&gt; queries, ensure that the columns used in the &lt;code&gt;ON&lt;/code&gt; clause, as well as other frequently queried columns like those in WHERE and ORDER BY clauses.&lt;/p&gt;

&lt;p&gt;Want to learn more about indexing strategies for PostgreSQL? Check out this &lt;a href="https://medium.com/the-software-firehose/how-to-choose-a-table-index-for-your-sql-database-d47715a35f34" rel="noopener noreferrer"&gt;resource on choosing table indexes.&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  My Decision
&lt;/h3&gt;

&lt;p&gt;After evaluating both the &lt;code&gt;IN&lt;/code&gt; and &lt;code&gt;JOIN&lt;/code&gt; approaches, I decided to use &lt;code&gt;JOIN&lt;/code&gt; in cases where the data is expected to grow, as it provides better performance with larger datasets. However, for situations where I know the data will remain small, I opted for &lt;code&gt;IN&lt;/code&gt; as it offers faster query execution for smaller datasets.&lt;/p&gt;

&lt;p&gt;Additionally, I’ve implemented indexing on key columns (like id's) to ensure that &lt;code&gt;JOIN&lt;/code&gt; queries continue to perform well as the application scales.&lt;/p&gt;




&lt;p&gt;In conclusion, &lt;strong&gt;always evaluate your use case, choose the most appropriate method based on data size, and monitor your queries over time&lt;/strong&gt; to ensure continued performance optimization as your data scales.&lt;/p&gt;

&lt;p&gt;Happy coding! 💻&lt;/p&gt;

</description>
      <category>django</category>
      <category>postgres</category>
      <category>performance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Docker 101: Basics and Practical Implementation with Spring REST API</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Tue, 22 Oct 2024 10:01:49 +0000</pubDate>
      <link>https://dev.to/priya01/docker-101-basics-and-practical-implementation-with-spring-rest-api-497g</link>
      <guid>https://dev.to/priya01/docker-101-basics-and-practical-implementation-with-spring-rest-api-497g</guid>
      <description>&lt;p&gt;&lt;strong&gt;Ever spent hours debugging an application only to find it works perfectly on your machine but breaks in production? This is a common frustration for developers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine a developer builds a web application that runs on Python 3.8 and needs specific libraries. In development, the app works perfectly. However, when deployed to a server running Python 3.9, it breaks due to compatibility issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, what's the solution?&lt;/strong&gt; Enter Docker.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.licdn.com%2Fdms%2Fimage%2Fv2%2FD5612AQGrDzZwx8xCtw%2Farticle-cover_image-shrink_600_2000%2Farticle-cover_image-shrink_600_2000%2F0%2F1702880752441%3Fe%3D2147483647%26v%3Dbeta%26t%3DSJV03jeSaZF1J2Fr8x4Xt6HVBPtr7FByH4wASJ2BwBw" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.licdn.com%2Fdms%2Fimage%2Fv2%2FD5612AQGrDzZwx8xCtw%2Farticle-cover_image-shrink_600_2000%2Farticle-cover_image-shrink_600_2000%2F0%2F1702880752441%3Fe%3D2147483647%26v%3Dbeta%26t%3DSJV03jeSaZF1J2Fr8x4Xt6HVBPtr7FByH4wASJ2BwBw" alt="docker" width="312" height="390"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
By using Docker, the developer can package the app with Python 3.8 and all necessary libraries in a container. This container can then be deployed anywhere without worrying about compatibility, ensuring it runs smoothly in any environment.&lt;/p&gt;

&lt;p&gt;In other words, it solves the "works on my machine" problem by ensuring that the application runs the same regardless of the environment.&lt;/p&gt;


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

&lt;p&gt;&lt;em&gt;Docker is a platform that allows developers to package applications and their dependencies into lightweight, portable containers. These containers ensure that an application runs the same way, regardless of the environment—whether it's on a developer's laptop, a testing server, or a production server.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding the Basics
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zszask2ul2luikzift5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zszask2ul2luikzift5.png" alt="Docker image-file-container" width="800" height="284"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Image credit: &lt;a href="https://medium.com/@senali/introduction-to-docker-c159e5b102c4" rel="noopener noreferrer"&gt;Senali&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Docker Hub
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker Hub is a cloud-based repository where you can store and share Docker images, allowing easy access for developers and teams. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Docker Image
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A Docker image is a lightweight, read-only, and executable software package that includes everything needed to run an application: code, runtime, libraries, environment variables, and configuration files.&lt;/li&gt;
&lt;li&gt;Think of an image as a blueprint for creating Docker containers. &lt;/li&gt;
&lt;li&gt;You can have multiple containers running from the same image.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Docker Container
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A Docker container is a running instance of a Docker image. It uses the image's content to execute an application.&lt;/li&gt;
&lt;li&gt;Containers can be stopped, started, or removed without affecting the Docker image.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;In simpler terms:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Image = Blueprint&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Container = Running Application&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Dockerfile
&lt;/h3&gt;

&lt;p&gt;A Dockerfile is a script that contains a series of instructions for building a Docker image. It specifies how the application should be packaged and run inside a container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; openjdk:17-jdk-alpine&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; JAR_FILE=target/*.jar&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ${JAR_FILE} app.jar&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["java", "-jar", "/app.jar"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;FROM&lt;/code&gt; specifies the base image to use (a base image contains the necessary software, libraries, and files required to run your application or service). Here, &lt;code&gt;openjdk&lt;/code&gt; is used because we are going to run a Java application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ARG&lt;/code&gt; defines a variable to reference the JAR file. Here, the value assigned is the Spring Boot JAR that is built by Maven, located in the target directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;COPY&lt;/code&gt; copies the JAR file into the container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ENTRYPOINT&lt;/code&gt; defines the command to run the application.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Docker Compose
&lt;/h3&gt;

&lt;p&gt;Docker Compose orchestrates multiple containers (for example, a Spring Boot app and MySQL). It defines how each container will be set up, how they communicate, and their environment configurations. The configuration for Docker Compose is specified in a YAML file, typically named &lt;code&gt;docker-compose.yml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mysql-db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql:8.0&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-db&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_DATABASE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;spring_docker_demo&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3306:3306"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;spring-network&lt;/span&gt;

  &lt;span class="na"&gt;spring-app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;spring-docker-demo:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;spring-app&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mysql-db&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;spring-network&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;SPRING_DATASOURCE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc:mysql://mysql-db:3306/spring_docker_demo&lt;/span&gt;
      &lt;span class="na"&gt;SPRING_DATASOURCE_USERNAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
      &lt;span class="na"&gt;SPRING_DATASOURCE_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;spring-network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;version&lt;/code&gt; specifies the Docker Compose version that we are using.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;services&lt;/code&gt; defines individual containers. In this case, &lt;code&gt;mysql-db&lt;/code&gt; is the first service and the second one is &lt;code&gt;spring-app&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;networks&lt;/code&gt; section defines a network named &lt;code&gt;spring-network&lt;/code&gt;. Both the Spring Boot app and MySQL will be on this network, allowing them to communicate with each other.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwkzz4r6qtrhvgwf5b33.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwkzz4r6qtrhvgwf5b33.png" alt="Docker network" width="751" height="415"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Image credit: &lt;a href="https://dhruv-saksena.medium.com/docker-compose-a-springboot-mysql-application-867c992eab9d" rel="noopener noreferrer"&gt;Dhruv Saksena&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Brief Overview of Services
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. MySQL (&lt;code&gt;mysql-db&lt;/code&gt;)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;image&lt;/code&gt;: Specifies the Docker image to use for this service. In this case, it's the official &lt;code&gt;mysql:8.0&lt;/code&gt; image.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;container_name&lt;/code&gt;: This gives a name to the MySQL container, making it easier to reference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;environment&lt;/code&gt;: Passes environment variables into the container. Here, we’re setting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;MYSQL_ROOT_PASSWORD&lt;/code&gt;: The root password for MySQL.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MYSQL_DATABASE&lt;/code&gt;: The name of the initial database to create.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ports&lt;/code&gt;: Maps the MySQL container's internal port (3306) to the host machine’s port (3306), allowing access to the database from the host.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;networks&lt;/code&gt;: Defines the network (&lt;code&gt;spring-network&lt;/code&gt;) that the MySQL container will join.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  2. Spring App (&lt;code&gt;spring-app&lt;/code&gt;)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;image&lt;/code&gt;: Specifies the Docker image to use for the Spring Boot app. In this case, it’s &lt;code&gt;spring-docker-demo:latest&lt;/code&gt;, which will be built from the Dockerfile in this project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;build&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;context&lt;/code&gt;: The directory where the Dockerfile and source code are located (. means the current directory).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dockerfile&lt;/code&gt;: The name of the Dockerfile to use (in this case, Dockerfile).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;depends_on&lt;/code&gt;: Specifies that the &lt;code&gt;spring-app&lt;/code&gt; service depends on the &lt;code&gt;mysql-db&lt;/code&gt; service, ensuring that MySQL starts before the Spring Boot app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ports&lt;/code&gt;: Maps the Spring Boot container’s internal port (8080) to the host machine’s port (8080), allowing access to the REST API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;networks&lt;/code&gt;: Defines the network that the Spring Boot container will join, allowing it to communicate with the MySQL container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;environment&lt;/code&gt;: Sets environment variables for the Spring Boot app. These variables override values in &lt;code&gt;application.properties&lt;/code&gt; and allow the Spring Boot app to connect to the MySQL container.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Example: Dockerizing a Spring REST API
&lt;/h2&gt;

&lt;p&gt;To understand it better, let me walk you through an example of dockerizing a Spring REST API.&lt;/p&gt;
&lt;h4&gt;
  
  
  1. &lt;strong&gt;Project Structure&lt;/strong&gt;:
&lt;/h4&gt;

&lt;p&gt;Before diving into the Docker configurations, ensure your project structure looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   spring-docker-demo/
   ├── Dockerfile
   ├── docker-compose.yml
   ├── src/
   │   └── main/
   │       └── java/
   │           └── com/
   │               └── example/
   │                   └── demo/
   │                       └── DemoApplication.java
   │                       └── UserController.java
   └── pom.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. &lt;strong&gt;Build the Spring Boot Application&lt;/strong&gt;:
&lt;/h4&gt;

&lt;p&gt;Make sure your Spring Boot application is set up correctly and build it using Maven:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn clean package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command should create a JAR file in the &lt;code&gt;target&lt;/code&gt; directory, which the Dockerfile will reference.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Using the Dockerfile&lt;/strong&gt;:
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;Dockerfile&lt;/code&gt; provided will be used to create an image for your Spring REST API, as discussed earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; openjdk:17-jdk-alpine&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; JAR_FILE=target/*.jar&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ${JAR_FILE} app.jar&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["java", "-jar", "/app.jar"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. &lt;strong&gt;Using Docker Compose&lt;/strong&gt;:
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;docker-compose.yml&lt;/code&gt; file will help you orchestrate the application and its database (MySQL). Here’s the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mysql-db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql:8.0&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-db&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_DATABASE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;spring_docker_demo&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3306:3306"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;spring-network&lt;/span&gt;

  &lt;span class="na"&gt;spring-app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;spring-docker-demo:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;spring-app&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mysql-db&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;spring-network&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;SPRING_DATASOURCE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc:mysql://mysql-db:3306/spring_docker_demo&lt;/span&gt;
      &lt;span class="na"&gt;SPRING_DATASOURCE_USERNAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
      &lt;span class="na"&gt;SPRING_DATASOURCE_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;spring-network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. &lt;strong&gt;Running the Application&lt;/strong&gt;:
&lt;/h4&gt;

&lt;p&gt;Navigate to your project folder where the &lt;code&gt;docker-compose.yml&lt;/code&gt; file is located and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command builds the Docker images and starts the containers for your application and the database.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. &lt;strong&gt;Accessing the Application&lt;/strong&gt;:
&lt;/h4&gt;

&lt;p&gt;Once everything is up and running, you can access your Spring REST API at &lt;code&gt;http://localhost:8080&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sharing Your Docker Image
&lt;/h2&gt;

&lt;p&gt;Once you've containerized your Spring REST API, sharing the Docker image with others is straightforward. &lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Build the Docker Image&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Build your image with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; your-username/spring-docker-demo:latest &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;your-username&lt;/code&gt; with your Docker Hub username and &lt;code&gt;.&lt;/code&gt; indicates that the Dockerfile is located in the current directory.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Push to Docker Hub&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Log in to Docker Hub and push your image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker login
docker push your-username/spring-docker-demo:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, replace &lt;code&gt;your-username&lt;/code&gt; with your actual Docker Hub username.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Pulling the Image&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Others can easily pull and run your image by executing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull your-username/spring-docker-demo:latest
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 your-username/spring-docker-demo:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pull&lt;/code&gt; command downloads your Docker image from Docker Hub to their local machine.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;run&lt;/code&gt; command runs a container from the downloaded image.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-d&lt;/code&gt;&lt;/strong&gt;: Runs the container in detached mode (in the background).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-p 8080:8080&lt;/code&gt;&lt;/strong&gt;: Maps port 8080 of the host machine to port 8080 of the container, allowing access to the application.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;Docker is a game-changer for developers, making deployment seamless and ensuring your app runs consistently across environments. Say goodbye to "it works on my machine" frustrations! &lt;/p&gt;

&lt;p&gt;Ready to dive into Docker? Share your experiences or questions below!&lt;/p&gt;

&lt;p&gt;Happy Coding! 🐳&lt;/p&gt;

</description>
      <category>docker</category>
      <category>springboot</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>From Contributor to Collaborator: My Hacktoberfest Journey</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Wed, 16 Oct 2024 07:06:20 +0000</pubDate>
      <link>https://dev.to/priya01/from-contributor-to-collaborator-my-hacktoberfest-journey-2443</link>
      <guid>https://dev.to/priya01/from-contributor-to-collaborator-my-hacktoberfest-journey-2443</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The best way to learn is to do; the best way to contribute is to share.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This year, I joined &lt;strong&gt;Hacktoberfest 2024&lt;/strong&gt; for the first time! Although I’ve contributed to open-source projects before, this was my first time joining Hacktoberfest, and my goal was not only to complete &lt;strong&gt;four PRs&lt;/strong&gt; (Pull Requests) but to learn more in the process. I was excited to learn from the open-source community and make my own impact.&lt;/p&gt;

&lt;p&gt;I started by looking for projects that matched my skills, especially something related to &lt;strong&gt;Spring Boot&lt;/strong&gt;. After some searching, I found an interesting project and spent a day setting up my environment and exploring the code.&lt;/p&gt;




&lt;h3&gt;
  
  
  My First Contribution: Pagination and Sorting 🎯
&lt;/h3&gt;

&lt;p&gt;Many issues were already taken by others, but I didn’t give up. Instead, I suggested my own feature: &lt;strong&gt;Pagination and Sorting&lt;/strong&gt; for API endpoints. The project maintainers liked my idea and assigned the task to me! I worked hard on this and submitted my first PR, which was &lt;strong&gt;merged on the same day&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;I can’t describe how happy I was when I got the email saying my PR was merged! The maintainers also gave positive feedback, which made me even more excited. We also worked together to improve the project documentation to include my changes.&lt;/p&gt;




&lt;h3&gt;
  
  
  Learning About Error Handling 🛠️
&lt;/h3&gt;

&lt;p&gt;While I was working on the documentation, I saw some errors in the code. I thought I could improve the project by adding better error handling. So, I submitted another PR to fix that—&lt;strong&gt;and it was merged too!&lt;/strong&gt; This taught me a lot about writing clean code and handling errors properly.&lt;/p&gt;

&lt;p&gt;I also submitted a PR to another repository, where I added an algorithm, which helped me expand my contributions.&lt;/p&gt;




&lt;h3&gt;
  
  
  Overcoming Challenges: Fixing My Algorithm 🔧
&lt;/h3&gt;

&lt;p&gt;Not everything was easy. One of my PRs related to an algorithm faced a check failure due to clang-format issues. After analyzing the situation, I quickly installed clang-format and formatted the code to adhere to the project’s style guidelines. After ensuring that my changes met the required formatting, I committed the updates and submitted the PR again. This experience taught me the importance of attention to detail and the necessity of understanding the tools in my development environment. While I was doing that, I also started exploring security issues in another project, which gave me a new challenge to work on.&lt;/p&gt;




&lt;h3&gt;
  
  
  Facing My Fears 🚀
&lt;/h3&gt;

&lt;p&gt;Next, I decided to add &lt;strong&gt;HTTPS/SSL&lt;/strong&gt; support to a custom server. At first, I was scared to work on this project because it seemed complicated. However, I broke it down and took the time to understand the code step by step. In the end, I successfully added HTTPS support and included security headers in the response. This was challenging, especially since I was using self-signed certificates. After overcoming these obstacles, I updated the docstring to explain my changes and submitted a PR for review.&lt;/p&gt;




&lt;h3&gt;
  
  
  More Achievements and a Surprise 🏆
&lt;/h3&gt;

&lt;p&gt;Remember? &lt;em&gt;"Hard work always pays off in the end."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the end, both my &lt;strong&gt;algorithm&lt;/strong&gt; and &lt;strong&gt;SSL/HTTPS&lt;/strong&gt; PRs were merged. But the best surprise came when I was offered to become a &lt;strong&gt;maintainer&lt;/strong&gt; for one of the repositories! I was so excited and accepted the offer right away. This gave me even more motivation to push myself, and I ended up submitting a total of &lt;strong&gt;nine PRs&lt;/strong&gt; during Hacktoberfest! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zy28ffy02ofhp5rl4q7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zy28ffy02ofhp5rl4q7.png" alt="My Holopin badges" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Helping Others: Reviewing PRs 🤝
&lt;/h3&gt;

&lt;p&gt;After submitting my PRs, I started reviewing issues and PRs from other contributors. It felt wonderful to help others, and when one of them said, “Thank you for teaching me something new about security; this will elevate my skill,” I was truly happy. This experience motivated me to continue contributing and supporting others in the community. It’s amazing to see how we can all learn from each other in the open-source world.&lt;/p&gt;




&lt;h3&gt;
  
  
  Lessons Learned 🌱
&lt;/h3&gt;

&lt;p&gt;Reflecting on this journey, here are some key takeaways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Effective Communication&lt;/strong&gt;: Contributing features like pagination taught me the importance of clear communication with maintainers to ensure alignment on project goals.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code Quality Matters&lt;/strong&gt;: Enhancing error handling reinforced that clean, well-documented code reduces errors and benefits other contributors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Attention to Detail&lt;/strong&gt;: The clang-format issue reminded me to adhere to project style guidelines and utilize tools that help maintain consistency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community Strength&lt;/strong&gt;: Reviewing PRs and helping others demonstrated the value of collaboration in the open-source community, inspiring me to continue growing alongside my peers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  My Hacktoberfest Journey ✨
&lt;/h3&gt;

&lt;p&gt;Hacktoberfest 2024 was an amazing experience for me! I learned so much, not just about coding, but also about being part of the open-source community. I recommend Hacktoberfest to everyone—it’s a great way to improve your skills and connect with others who are passionate about coding.&lt;/p&gt;

&lt;p&gt;Thank you for reading my Hacktoberfest story! I hope it inspires you to join the event and experience the joy of contributing to open source.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hacktoberfest</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Spring Boot Meets Firebase: My Journey of Building a File Upload System</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Thu, 03 Oct 2024 16:02:53 +0000</pubDate>
      <link>https://dev.to/priya01/spring-boot-meets-firebase-my-journey-of-building-a-file-upload-system-4m3i</link>
      <guid>https://dev.to/priya01/spring-boot-meets-firebase-my-journey-of-building-a-file-upload-system-4m3i</guid>
      <description>&lt;p&gt;Recently, I created a REST API for uploading and retrieving files using Spring Boot and Firebase. This project was driven by my interest after seeing someone mention they were having issues with file uploads in Spring Boot. In an effort to help, I decided to familiarize myself with file uploads using Spring Boot and Firebase.&lt;/p&gt;

&lt;p&gt;So, if you’re like me and want to get familiar with file management using Firebase and Spring Boot, let’s get started! 😊&lt;/p&gt;




&lt;h2&gt;
  
  
  First Up: Setting Up Firebase 🛠️
&lt;/h2&gt;

&lt;p&gt;Before we dive into the code, the first step is setting up Firebase to handle file uploads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create a Firebase Project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to the Firebase Console: &lt;a href="https://console.firebase.google.com/" rel="noopener noreferrer"&gt;Firebase Console&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a New Project:

&lt;ul&gt;
&lt;li&gt;Enter a project name.&lt;/li&gt;
&lt;li&gt;Click "Continue" and select whether to enable Google Analytics (optional).&lt;/li&gt;
&lt;li&gt;Click "Create Project."&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Enable Cloud Storage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open Your Project: In the Firebase console, select your project.&lt;/li&gt;
&lt;li&gt;Navigate to Cloud Storage:

&lt;ul&gt;
&lt;li&gt;Click on “Build &amp;gt; Storage” in the left sidebar.&lt;/li&gt;
&lt;li&gt;Click on “Get Started” and "Start in test mode (or production if needed)" to enable Cloud Storage for your project.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Get Your Service Account Key 🔑
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6c36cq06pijwv5lcxaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6c36cq06pijwv5lcxaj.png" alt="Service Account Key" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to "Project Settings" &amp;gt; "Service accounts."&lt;/li&gt;
&lt;li&gt;Click on “Generate new private key,” and a JSON file will be downloaded. Keep this file secure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it for Firebase setup! Now, let’s move on to integrating it with Spring Boot.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next: Setting Up Spring Boot ⚙️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a Spring Boot Project
&lt;/h3&gt;

&lt;p&gt;You can create a Spring Boot project using Spring Initializr.&lt;/p&gt;

&lt;p&gt;Select the following dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spring Web&lt;/strong&gt;: For building REST APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Boot DevTools&lt;/strong&gt; (optional, for easier development).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Add Firebase Dependencies
&lt;/h3&gt;

&lt;p&gt;Add the Firebase dependency to your &lt;code&gt;pom.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.google.firebase&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;firebase-admin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;8.1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Firebase Configuration
&lt;/h3&gt;

&lt;p&gt;You need to set up Firebase authentication using the &lt;code&gt;.json&lt;/code&gt; key file you downloaded earlier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Place the &lt;code&gt;.json&lt;/code&gt; file in your &lt;code&gt;src/main/resources&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Then, create a configuration class &lt;code&gt;FirebaseConfig&lt;/code&gt; to initialize Firebase:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FirebaseConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="nc"&gt;FirebaseApp&lt;/span&gt; &lt;span class="nf"&gt;firebaseApp&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;ClassPathResource&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClassPathResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"serviceAccountKey.json"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
        &lt;span class="nc"&gt;InputStream&lt;/span&gt; &lt;span class="n"&gt;serviceAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;FirebaseOptions&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FirebaseOptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setProjectId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fir-fileuploadapi"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCredentials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;GoogleCredentials&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceAccount&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStorageBucket&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fir-fileuploadapi.appspot.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDatabaseUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://fir-fileuploadapi-default-rtdb.firebaseio.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;FirebaseApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initializeApp&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, replace the &lt;code&gt;projectId&lt;/code&gt;, &lt;code&gt;bucketName&lt;/code&gt;, and &lt;code&gt;databaseUrl&lt;/code&gt; with your own details from Firebase.&lt;/p&gt;

&lt;p&gt;Where to get those?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project ID&lt;/strong&gt;: Firebase console &amp;gt; Your project (that you created earlier) &amp;gt; Project settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe7t4hubby7yvvdlrqk4x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe7t4hubby7yvvdlrqk4x.png" alt="Project ID" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bucket Name&lt;/strong&gt;: Firebase console &amp;gt; Your project &amp;gt; Build &amp;gt; Storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftiygdaysr1e5l5qo60bq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftiygdaysr1e5l5qo60bq.png" alt="Bucket Name" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database URL&lt;/strong&gt;: Firebase console &amp;gt; Your project &amp;gt; Build &amp;gt; Realtime Database &amp;gt; Create Database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6p6kuw6k3kvkgad9f28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6p6kuw6k3kvkgad9f28.png" alt="Database URL" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, your database URL will be shown at the top.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17y4s918mn45u4tebyh0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17y4s918mn45u4tebyh0.png" alt="Database URL Top" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Create a Service
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;FileStorageService&lt;/code&gt; class with a constructor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileStorageService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Storage&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;FileMetaDataRepository&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;bucketName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fir-fileuploadapi.appspot.com"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;FileStorageService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FileMetaDataRepository&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;ClassPathResource&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClassPathResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"serviceAccountKey.json"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;InputStream&lt;/span&gt; &lt;span class="n"&gt;serviceAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;GoogleCredentials&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GoogleCredentials&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceAccount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createScoped&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Lists&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newArrayList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://www.googleapis.com/auth/cloud-platform"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StorageOptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setCredentials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getService&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, just replace &lt;code&gt;serviceAccountKey.json&lt;/code&gt; with the name of the JSON file stored in the &lt;code&gt;src/main/resources&lt;/code&gt; folder and the &lt;code&gt;Bucket Name&lt;/code&gt; you got earlier.&lt;/p&gt;

&lt;p&gt;Wait! What is &lt;code&gt;FileMetaDataRepository&lt;/code&gt;? We haven't created that yet.&lt;/p&gt;

&lt;p&gt;Here you go!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;FileMetaDataRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FileMetaData&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;FileMetaData&lt;/span&gt; &lt;span class="nf"&gt;findByUniqueId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;uniqueId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the corresponding &lt;code&gt;FileMetaData.java&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Entity&lt;/span&gt;
&lt;span class="nd"&gt;@Table&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"files"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileMetaData&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Id&lt;/span&gt;
    &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IDENTITY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"unique_id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;uniqueId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"object_name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"upload_date"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;LocalDateTime&lt;/span&gt; &lt;span class="n"&gt;uploadDate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;FileMetaData&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;FileMetaData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;uniqueId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;LocalDateTime&lt;/span&gt; &lt;span class="n"&gt;uploadDate&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uniqueId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uniqueId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;objectName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uploadDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uploadDate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// getters and setters go here...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What’s the need for this? &lt;/p&gt;

&lt;p&gt;&lt;code&gt;FileMetaData&lt;/code&gt; is an object that holds metadata (data about the data) about the file we are storing. It's just for making our retrieval smoother! &lt;/p&gt;

&lt;h3&gt;
  
  
  5. Create the Uploading and Retrieving Methods
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Uploading Files
&lt;/h4&gt;

&lt;p&gt;In the &lt;code&gt;FileStorageService&lt;/code&gt;, we’ll create a method for uploading files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;uploadFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MultipartFile&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File is empty. Please upload a valid file."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;uniqueID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;randomUUID&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;objectName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uniqueID&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"_"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOriginalFilename&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;BlobId&lt;/span&gt; &lt;span class="n"&gt;blobId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BlobId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucketName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nc"&gt;BlobInfo&lt;/span&gt; &lt;span class="n"&gt;blobInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BlobInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blobId&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blobInfo&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="nc"&gt;FileMetaData&lt;/span&gt; &lt;span class="n"&gt;metaData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileMetaData&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;metaData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUniqueId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uniqueID&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;metaData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setObjectName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;metaData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUploadDate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LocalDateTime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metaData&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;uniqueID&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;We first check if the uploaded file is empty. If it is, we throw an exception.&lt;/li&gt;
&lt;li&gt;We generate a unique ID for the file using &lt;code&gt;UUID&lt;/code&gt; to ensure no two files have the same identifier.&lt;/li&gt;
&lt;li&gt;We create a &lt;code&gt;BlobId&lt;/code&gt; and &lt;code&gt;BlobInfo&lt;/code&gt; for the file, then store the file in Firebase using the &lt;code&gt;storage.create()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Finally, we save the file metadata in our repository for easy retrieval later.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Retrieving Files
&lt;/h4&gt;

&lt;p&gt;Now, let’s create a method to retrieve files by their unique ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;FileResponse&lt;/span&gt; &lt;span class="nf"&gt;retrieveFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fileId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;FileMetaData&lt;/span&gt; &lt;span class="n"&gt;fileMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByUniqueId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileMetadata&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No file found with the given ID: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fileId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;objectName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileMetadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getObjectName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;BlobId&lt;/span&gt; &lt;span class="n"&gt;blobId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BlobId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucketName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;Blob&lt;/span&gt; &lt;span class="n"&gt;blob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blobId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exists&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No file found with the given ID: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fileId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;FileResponse&lt;/span&gt; &lt;span class="n"&gt;fileResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getContent&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fileResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;We look up the file metadata by its unique ID. If it doesn't exist, we throw an exception.&lt;/li&gt;
&lt;li&gt;We retrieve the &lt;code&gt;Blob&lt;/code&gt; from Firebase using the object name stored in our metadata.&lt;/li&gt;
&lt;li&gt;If the blob exists, we create a &lt;code&gt;FileResponse&lt;/code&gt; object that contains the file name and its content, ready to be returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is how the &lt;code&gt;FileResponse&lt;/code&gt; class looks like,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileResponse&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;fileContent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;FileResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;fileContent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fileContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileContent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getFileName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;getFileContent&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fileContent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Create a Controller
&lt;/h3&gt;

&lt;p&gt;Next, we’ll set up a controller to handle our HTTP requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/files"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileStorageController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;FileStorageService&lt;/span&gt; &lt;span class="n"&gt;fileStorageService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/upload"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;uploadFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&lt;/span&gt; &lt;span class="nc"&gt;MultipartFile&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fileId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileStorageService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uploadFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;

&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/retrieve/{fileId}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FileResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;retrieveFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fileId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;FileResponse&lt;/span&gt; &lt;span class="n"&gt;fileResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileStorageService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;retrieveFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileResponse&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;uploadFile&lt;/code&gt; method handles file uploads by calling our service method and returning the unique ID.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;retrieveFile&lt;/code&gt; method fetches the file using the unique ID and returns its content.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Testing the API 🧪
&lt;/h2&gt;

&lt;p&gt;Now that everything is set up, you can test your API using Postman or any other tool.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;To Upload a File&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make a &lt;code&gt;POST&lt;/code&gt; request to &lt;code&gt;http://localhost:8080/api/files/upload&lt;/code&gt; with the file in the form-data.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;To Retrieve a File&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make a &lt;code&gt;GET&lt;/code&gt; request to &lt;code&gt;http://localhost:8080/api/files/retrieve/{fileId}&lt;/code&gt; using the unique ID you received from the upload response.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




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

&lt;p&gt;And there you have it! You’ve successfully created a Spring Boot REST API to upload and retrieve files using Firebase. I hope this guide was helpful and easy to follow! If you have any questions or need further assistance, feel free to drop a comment below! &lt;/p&gt;

&lt;p&gt;Happy coding! 💻&lt;/p&gt;

</description>
      <category>firebase</category>
      <category>springboot</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Boost Your Java Code Quality with PMD</title>
      <dc:creator>Priya</dc:creator>
      <pubDate>Fri, 20 Sep 2024 16:12:41 +0000</pubDate>
      <link>https://dev.to/priya01/boost-your-java-code-quality-with-pmd-56id</link>
      <guid>https://dev.to/priya01/boost-your-java-code-quality-with-pmd-56id</guid>
      <description>&lt;p&gt;Do you ever find yourself struggling with code smells in your Java projects? You’re not alone! Code smells are simply indicators that your code could use some improvement. In this post, we'll explore how &lt;em&gt;PMD (Programming Mistake Detector)&lt;/em&gt; can help you find and fix these pesky code smells effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Code Smells?
&lt;/h2&gt;

&lt;p&gt;Code smells aren’t bugs, but they do suggest that your code could use some improvement to make it clearer, easier to maintain, or more efficient. Here are a few common examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Long Methods:&lt;/strong&gt; These are methods that are too long and try to do too many things at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Duplicated Code:&lt;/strong&gt; This is when you see the same code in several places.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep Nesting:&lt;/strong&gt; This happens when your code has too many nested blocks, making it tough to read.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;em&gt;PMD&lt;/em&gt; (Programming Mistake Detector) is a handy tool that analyzes your source code to spot common programming issues. It helps identify things like unused variables, empty catch blocks, and overly complex methods, making it easier for you to improve your code quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rulesets in PMD
&lt;/h2&gt;

&lt;p&gt;PMD uses predefined rulesets to check your code. These rulesets have different rules that look for various kinds of issues. Here’s a quick look at some common rulesets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Basic:&lt;/strong&gt; Looks for simple issues like empty catch blocks and unnecessary object creation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design:&lt;/strong&gt; Checks if your code follows good design principles and finds overly complex methods and classes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unused Code:&lt;/strong&gt; Finds code elements that are defined but never used.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Integrate PMD into Your Build Process
&lt;/h2&gt;

&lt;p&gt;Integrating PMD into your build process helps you automatically check for code quality. Here’s how to set it up with Maven:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Add PMD Plugin to &lt;code&gt;pom.xml&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-pmd-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.21.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;rulesets&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;ruleset&amp;gt;&lt;/span&gt;java-basic&lt;span class="nt"&gt;&amp;lt;/ruleset&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;ruleset&amp;gt;&lt;/span&gt;java-design&lt;span class="nt"&gt;&amp;lt;/ruleset&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;ruleset&amp;gt;&lt;/span&gt;java-unusedcode&lt;span class="nt"&gt;&amp;lt;/ruleset&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/rulesets&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;verify&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;pmd&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;rulesets&amp;gt;&lt;/code&gt;&lt;/strong&gt;: This tells PMD which rulesets to use (like basic, design, and unused code).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;phase&amp;gt;verify&amp;lt;/phase&amp;gt;&lt;/code&gt;&lt;/strong&gt;: This sets PMD to run during the Maven &lt;code&gt;verify&lt;/code&gt; phase, which happens after tests and before packaging your code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Run PMD
&lt;/h4&gt;

&lt;p&gt;You can run PMD during your Maven build or on its own.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;During Build:&lt;/strong&gt; PMD will run automatically during the &lt;code&gt;verify&lt;/code&gt; phase when you run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  mvn clean verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manually:&lt;/strong&gt; If you want to run PMD separately, just use:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  mvn pmd:pmd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will kick off the PMD analysis.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. View Reports
&lt;/h4&gt;

&lt;p&gt;After PMD runs, it generates a report showing any issues it found.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Locate the Report:&lt;/strong&gt; You can find the PMD report at:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  target/site/pmd.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Report Contents:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Summary:&lt;/strong&gt; A quick overview of how many violations were found.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Details:&lt;/strong&gt; A list of issues, including file names, line numbers, and descriptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rulesets:&lt;/strong&gt; Information about which rulesets were used and their results.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example Walkthrough
&lt;/h2&gt;

&lt;p&gt;Here’s a simple example to show PMD in action! You can check out the code in my &lt;a href="https://replit.com/@priya-01/PMD-Demo" rel="noopener noreferrer"&gt;Replit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Consider the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UnusedCode&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// This field is never used&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;unusedField&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;usedMethod&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This method is used."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;UnusedCode&lt;/span&gt; &lt;span class="n"&gt;unusedCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UnusedCode&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running &lt;code&gt;mvn pmd:pmd&lt;/code&gt;, you’ll find the report &lt;code&gt;pmd.html&lt;/code&gt; in the &lt;code&gt;target/site/&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;If you open it in your browser, it will look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6vsp15v0sq5l24rk6vi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6vsp15v0sq5l24rk6vi.png" alt="PMD Report" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the PMD Report
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Overview:&lt;/strong&gt; Displays the PMD version (6.55.0) and last published date.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Violations by Priority:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Main.java:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rule:&lt;/strong&gt; &lt;a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_design.html#useutilityclass" rel="noopener noreferrer"&gt;UseUtilityClass&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Violation:&lt;/strong&gt; "All methods are static. Consider using a utility class."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Line:&lt;/strong&gt; 1–5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UnusedCode.java:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rule:&lt;/strong&gt; &lt;a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_bestpractices.html#unusedprivatefield" rel="noopener noreferrer"&gt;UnusedPrivateField&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Violation:&lt;/strong&gt; "Avoid unused private fields."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Line:&lt;/strong&gt; 3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Files Section:&lt;/strong&gt; Details about violations for each analyzed file, highlighting areas for improvement.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Stopping Build Process if There Are Violations
&lt;/h2&gt;

&lt;p&gt;When PMD finds errors during a Maven build, the build doesn’t stop by default. It will report the violations and keep going. &lt;/p&gt;

&lt;p&gt;You can change this behavior so the build fails if certain limits of violations are hit. Here’s how:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-pmd-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.21.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;rulesets&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;ruleset&amp;gt;&lt;/span&gt;java-basic&lt;span class="nt"&gt;&amp;lt;/ruleset&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;ruleset&amp;gt;&lt;/span&gt;java-design&lt;span class="nt"&gt;&amp;lt;/ruleset&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;ruleset&amp;gt;&lt;/span&gt;java-unusedcode&lt;span class="nt"&gt;&amp;lt;/ruleset&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/rulesets&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;verify&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;pmd&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="c"&gt;&amp;lt;!-- Checks for violations and fails the build if found --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;check&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;goal&amp;gt;check&amp;lt;/goal&amp;gt;&lt;/code&gt;: This tells PMD to check for violations in the report. If any are found, it will fail the build.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, if you run &lt;code&gt;mvn clean verify&lt;/code&gt;, your build will stop if there are violations.&lt;/p&gt;

&lt;p&gt;Before adding the &lt;code&gt;check goal&lt;/code&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzhgawu2e5fd24kvl2lz7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzhgawu2e5fd24kvl2lz7.png" alt="Build Success Image" width="707" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After adding it,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpk8nqtrshkqbgqlqsmvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpk8nqtrshkqbgqlqsmvz.png" alt="Build Failed Image" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;By integrating PMD into your Java projects, you can automatically spot and fix code smells, making your code more maintainable and efficient. &lt;/p&gt;

&lt;p&gt;Feel free to share your experiences with PMD or ask any questions in the comments below. &lt;/p&gt;

&lt;p&gt;Happy coding! 😊&lt;/p&gt;

</description>
      <category>java</category>
      <category>codequality</category>
      <category>pmd</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
