<?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: Rakshyak Satpathy</title>
    <description>The latest articles on DEV Community by Rakshyak Satpathy (@rakshyak).</description>
    <link>https://dev.to/rakshyak</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%2F1231893%2Fb6bec096-0976-43aa-b4de-09524e6fa32d.png</url>
      <title>DEV Community: Rakshyak Satpathy</title>
      <link>https://dev.to/rakshyak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rakshyak"/>
    <language>en</language>
    <item>
      <title>"Works on My Machine" Is Not a Dev Strategy</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Sun, 12 Apr 2026 16:51:16 +0000</pubDate>
      <link>https://dev.to/rakshyak/works-on-my-machine-is-not-a-dev-strategy-1l4o</link>
      <guid>https://dev.to/rakshyak/works-on-my-machine-is-not-a-dev-strategy-1l4o</guid>
      <description>&lt;p&gt;New dev joins the team. Day 1: can't run the app 😅 Day 2: still can't run the app 💀 Day 3: senior dev drops everything to help 🫠 Sound familiar? I fixed this with Docker Compose and I'm never going back. Here's the full breakdown 🐳🔥&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How I stopped losing half my day to environment issues and gave our team a production-like local stack that just works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Setup&lt;br&gt;
I work on a property management system — the kind of software that hotels, hostels, and rental operators use to manage bookings, guests, room inventory, and payments. On the surface it sounds like a straightforward CRUD app. But in practice, a PMS is a web of interdependent services: a reservation API, a worker that processes booking events, a cache layer, a notification system, and a relational database holding years of critical guest and room data.&lt;br&gt;
For a long time, running this system locally meant one thing: pain.&lt;/p&gt;
&lt;h2&gt;
  
  
  Part 1 — Why We Needed to Change
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The "Works on My Machine" Graveyard
&lt;/h3&gt;

&lt;p&gt;Every team reaches a point where the phrase &lt;em&gt;"it works on my machine"&lt;/em&gt; stops being a joke and starts being a root cause in post-mortems. We reached that point.&lt;/p&gt;

&lt;p&gt;Our team had three engineers, three different operating systems, and no agreed-upon way to run the stack locally. One person was on macOS with Node 18, another on Ubuntu with Node 20, and a third on Windows with WSL2. Dependency versions drifted silently. Environment variables were passed around in Slack DMs. &lt;code&gt;npm install&lt;/code&gt; on a fresh clone would fail with cryptic native module errors that took an hour to debug — not because the code was wrong, but because the &lt;em&gt;environment&lt;/em&gt; was wrong.&lt;/p&gt;

&lt;p&gt;This is not a team problem. It is a systems problem. And it compounds fast.&lt;/p&gt;
&lt;h3&gt;
  
  
  The True Cost of Environment Inconsistency
&lt;/h3&gt;

&lt;p&gt;Let's be honest about what we were actually losing. Every new engineer onboarding spent the better part of a day — sometimes two — just getting the app to run locally. Senior engineers would pair with them, pulling them away from actual feature work. The entire overhead was invisible in sprint planning because nobody tracked it as a cost.&lt;/p&gt;

&lt;p&gt;Beyond onboarding, there was the subtler daily tax: environment-related bugs. A query that worked locally against a developer's personal Postgres instance would behave differently against staging because the database versions didn't match. Redis cache behavior differed between developers because some had it installed globally, some via Homebrew, and one was mocking it entirely. We were not testing the application; we were testing our individual setups.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why a PMS Specifically Needs This Solved
&lt;/h3&gt;

&lt;p&gt;A property management system is not a single service. It is at minimum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;reservation API&lt;/strong&gt; handling room availability, booking creation, and guest management&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;worker service&lt;/strong&gt; processing booking events — sending confirmation emails, updating inventory, triggering payment captures&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;PostgreSQL database&lt;/strong&gt; storing rooms, bookings, guests, pricing rules, and audit logs&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Redis instance&lt;/strong&gt; acting as a job queue and session cache&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;reverse proxy&lt;/strong&gt; routing external requests to the right internal service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These components have hard dependencies on each other. The API cannot start without the database being ready. The worker cannot function without Redis. The proxy cannot route without both application services being up. Running these independently, manually, in the correct order, every single time a developer sits down to work — is a coordination problem that scales terribly.&lt;/p&gt;

&lt;p&gt;The solution is not discipline. The solution is removing the coordination problem entirely.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 2 — The Problem Statement
&lt;/h2&gt;
&lt;h3&gt;
  
  
  What We Actually Needed
&lt;/h3&gt;

&lt;p&gt;Before reaching for a tool, it is worth being precise about the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We needed local environments that were:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reproducible — same behavior across macOS, Linux, and Windows&lt;/li&gt;
&lt;li&gt;Isolated — no dependency on globally installed software&lt;/li&gt;
&lt;li&gt;Ordered — services that start in the correct sequence, automatically&lt;/li&gt;
&lt;li&gt;Realistic — close enough to production that bugs caught locally stay caught&lt;/li&gt;
&lt;li&gt;Fast to start — from a fresh clone to a running stack in under two minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;We did not have any of this.&lt;/strong&gt; What we had was a collection of &lt;code&gt;README&lt;/code&gt; sections titled &lt;em&gt;"Prerequisites"&lt;/em&gt; that slowly fell out of date, a global Postgres installation that lived only on one developer's machine, and a habit of keeping services running in background terminal tabs and praying nobody rebooted.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Specific Failure Modes We Kept Hitting
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Race conditions on startup.&lt;/strong&gt; The API would try to connect to Postgres before Postgres had finished initializing. The fix was manually waiting, which meant either a &lt;code&gt;sleep 5&lt;/code&gt; in a shell script or just re-running the API and hoping. Neither is acceptable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seed data drift.&lt;/strong&gt; Each developer had a slightly different local database state. Testing the same feature against different data produced different results, making it impossible to reproduce bugs reliably. "Send me your database dump" became a recurring request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No queue visibility.&lt;/strong&gt; The worker service processed jobs from Redis. Locally, most developers skipped Redis entirely and mocked the queue. This meant an entire class of bugs — failed retries, duplicate processing, stale jobs — was completely invisible until staging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Onboarding friction as a product problem.&lt;/strong&gt; When a new engineer cannot contribute for two days because of environment setup, that is not just a developer experience issue. It is a product velocity issue. It delays features, drains senior engineering time, and signals to new team members that the codebase is harder to work with than it needs to be.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 3 — The Solution and Migration Approach
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Why Docker Compose
&lt;/h3&gt;

&lt;p&gt;Docker Compose solves exactly the class of problem described above. It lets you define your entire application stack — every service, every dependency, every network connection, every volume — in a single declarative file. Running &lt;code&gt;docker compose up&lt;/code&gt; becomes the one command that does everything.&lt;/p&gt;

&lt;p&gt;More importantly, it makes the environment part of the codebase. The &lt;code&gt;docker-compose.yml&lt;/code&gt; file lives in version control alongside the application code. When the Postgres version changes, that change is tracked, reviewed, and deployed consistently to every developer the next time they pull.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Target Architecture
&lt;/h3&gt;

&lt;p&gt;Before writing a single line of configuration, it helps to have a clear picture of what you are building.&lt;/p&gt;

&lt;p&gt;The stack has five core services and two optional observability services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nginx&lt;/strong&gt; sits at the edge, receiving traffic on port 80 and routing it to the appropriate internal service&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next.js API&lt;/strong&gt; handles all reservation, room, and guest operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Booking Worker&lt;/strong&gt; is a Node.js process that consumes jobs from a Redis queue and handles side effects — emails, inventory updates, payment triggers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt; is the source of truth for all relational data, seeded with realistic room and booking fixtures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis&lt;/strong&gt; serves two roles: session cache for the API and job queue for the worker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adminer&lt;/strong&gt; is a lightweight database UI exposed only in development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus + Grafana&lt;/strong&gt; form an optional observability layer for developers who want to understand service behavior under load&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  The Repository Structure
&lt;/h3&gt;

&lt;p&gt;Keeping the project navigable matters. Here is the structure that works well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pms-local-dev/
├── docker-compose.yml          # development stack
├── docker-compose.prod.yml     # production overrides
├── .env.example                # all variables documented, no secrets committed
├── Makefile                    # human-friendly command aliases
├── nginx/
│   └── nginx.conf              # routing rules, rate limiting
├── services/
│   ├── api/
│   │   ├── Dockerfile          # multi-stage: builder → runner
│   │   └── ...                 # Next.js application
│   └── worker/
│       ├── Dockerfile
│       └── ...                 # event processor
└── db/
    ├── seed.sql                # rooms, booking types, guest schema
    └── migrations/             # version-controlled schema changes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1 — Write Multi-Stage Dockerfiles
&lt;/h3&gt;

&lt;p&gt;The single biggest mistake in containerizing a Node.js application is treating the development image and the production image as the same thing. They are not.&lt;/p&gt;

&lt;p&gt;A development image needs devDependencies, source maps, and a file watcher for hot-reload. A production image needs none of that. Shipping a production image with everything included is how you end up with a 900MB container that takes three minutes to pull in CI.&lt;/p&gt;

&lt;p&gt;Multi-stage builds solve this cleanly:&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="c"&gt;# Stage 1: install all dependencies and build&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="c"&gt;# Stage 2: production image — only what runs&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;runner&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV=production&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/.next ./.next&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/public ./public&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/node_modules ./node_modules&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/package.json ./package.json&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In development, you override the command via Compose to run &lt;code&gt;npm run dev&lt;/code&gt; and mount the source directory as a bind volume. The container runs, the watcher picks up file changes, and hot-reload works exactly as it would outside Docker — without the environment fragmentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Write the Compose File with Health Checks
&lt;/h3&gt;

&lt;p&gt;This is the core of the solution. The key insight is the &lt;code&gt;depends_on&lt;/code&gt; condition. By attaching a health check to each dependency service and using &lt;code&gt;condition: service_healthy&lt;/code&gt; in the dependent service, you eliminate the startup race condition entirely. Postgres will be accepting connections before the API attempts its first query.&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres&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;postgres:16-alpine&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;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_DB}&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_USER}&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_PASSWORD}&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pg_data:/var/lib/postgresql/data&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./db/seed.sql:/docker-entrypoint-initdb.d/seed.sql&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&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;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg_isready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-U&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${POSTGRES_USER}"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;

  &lt;span class="na"&gt;redis&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;redis:7-alpine&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&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;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;redis-cli"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ping"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;

  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&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;./services/api&lt;/span&gt;
      &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;builder&lt;/span&gt; &lt;span class="c1"&gt;# use builder stage in dev for hot-reload&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./services/api:/app&lt;/span&gt; &lt;span class="c1"&gt;# bind mount for live code changes&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/app/node_modules&lt;/span&gt; &lt;span class="c1"&gt;# anonymous volume prevents host modules overwriting container&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;DATABASE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}&lt;/span&gt;
      &lt;span class="na"&gt;REDIS_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis://redis:6379&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;
      &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run dev&lt;/span&gt;

  &lt;span class="na"&gt;worker&lt;/span&gt;&lt;span class="pi"&gt;:&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;./services/worker&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;DATABASE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}&lt;/span&gt;
      &lt;span class="na"&gt;REDIS_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis://redis:6379&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;
      &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;

  &lt;span class="na"&gt;nginx&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;nginx:alpine&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;80:80"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./nginx/nginx.conf:/etc/nginx/nginx.conf:ro&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;api&lt;/span&gt;

  &lt;span class="na"&gt;adminer&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;adminer&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;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;postgres&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pg_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things worth noting here. The &lt;code&gt;pg_data&lt;/code&gt; named volume means your database persists across &lt;code&gt;docker compose down&lt;/code&gt; and &lt;code&gt;docker compose up&lt;/code&gt; cycles — you do not lose seed data every time you restart. The anonymous volume for &lt;code&gt;node_modules&lt;/code&gt; is a subtlety that trips people up: without it, the host's &lt;code&gt;node_modules&lt;/code&gt; (or lack thereof) would overwrite the container's, breaking native modules compiled inside the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Handle the Dev vs Production Split
&lt;/h3&gt;

&lt;p&gt;You do not want Adminer, bind mounts, and the builder stage target in production. The cleanest way to handle this is a Compose override file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose.prod.yml&lt;/code&gt; extends the base file and applies production-specific values:&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&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;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;runner&lt;/span&gt; &lt;span class="c1"&gt;# use the lean production stage&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;# no bind mounts&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm start&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;

  &lt;span class="na"&gt;worker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;

  &lt;span class="na"&gt;adminer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;profiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt; &lt;span class="c1"&gt;# only runs if explicitly activated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In production or CI, you run:&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 &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yml &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.prod.yml up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In development, you just run &lt;code&gt;docker compose up&lt;/code&gt;. The override pattern keeps both worlds maintainable in the same repository without duplication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 — Add a Makefile for Developer Ergonomics
&lt;/h3&gt;

&lt;p&gt;Nobody should have to remember &lt;code&gt;docker compose -f docker-compose.yml -f docker-compose.prod.yml up --build -d&lt;/code&gt;. A Makefile wraps the commands you actually use:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="nl"&gt;down&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    docker compose down

&lt;span class="nl"&gt;logs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    docker compose logs &lt;span class="nt"&gt;-f&lt;/span&gt;

&lt;span class="nl"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    docker compose &lt;span class="nb"&gt;exec &lt;/span&gt;postgres psql &lt;span class="nt"&gt;-U&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt;POSTGRES_USER &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt;POSTGRES_DB &lt;span class="nt"&gt;-f&lt;/span&gt; /docker-entrypoint-initdb.d/seed.sql

&lt;span class="nl"&gt;reset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    docker compose down &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker compose up &lt;span class="nt"&gt;--build&lt;/span&gt;

&lt;span class="nl"&gt;shell-api&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    docker compose &lt;span class="nb"&gt;exec &lt;/span&gt;api sh

&lt;span class="nl"&gt;shell-db&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    docker compose &lt;span class="nb"&gt;exec &lt;/span&gt;postgres psql &lt;span class="nt"&gt;-U&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt;POSTGRES_USER &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt;POSTGRES_DB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now onboarding is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &amp;lt;repo&amp;gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
make up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is it. Three commands. No prerequisite installations. No version mismatches. No Slack DMs about which version of Postgres to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 — The Migration Path for Existing Teams
&lt;/h3&gt;

&lt;p&gt;If you are retrofitting an existing PMS codebase rather than starting fresh, the migration does not need to happen all at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 1 — containerize the database only.&lt;/strong&gt; Get Postgres and Redis running in Docker while keeping the application running natively. This alone solves the most common source of environment drift and is the lowest-risk change. Developers connect to &lt;code&gt;localhost:5432&lt;/code&gt; as before — nothing about the application changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 2 — containerize the worker.&lt;/strong&gt; The worker is usually stateless and has no hot-reload requirements, making it the easiest service to containerize fully. Move it into Docker and verify it processes jobs from the Redis container correctly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 3 — containerize the API.&lt;/strong&gt; This is the most involved step. Set up the multi-stage Dockerfile, configure bind mounts for hot-reload, and verify the development experience matches what developers had before. Test on all three operating systems your team uses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 4 — add Nginx and the Makefile.&lt;/strong&gt; Complete the stack with the reverse proxy, verify the full startup sequence with health checks, document the commands in the Makefile, and update the README.&lt;/p&gt;

&lt;p&gt;This incremental approach means you can stop at any step if something is blocking, and you get value from each step independently. The full stack is the goal, but you do not need to pause feature work to get there.&lt;/p&gt;




</description>
      <category>docker</category>
    </item>
    <item>
      <title>Fixing Kafka Connectivity Issues Between Node.js and Docker Containers</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Sun, 16 Feb 2025 20:22:25 +0000</pubDate>
      <link>https://dev.to/rakshyak/fixing-kafka-connectivity-issues-between-nodejs-and-docker-containers-515b</link>
      <guid>https://dev.to/rakshyak/fixing-kafka-connectivity-issues-between-nodejs-and-docker-containers-515b</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Apache Kafka is a powerful event streaming platform, but setting it up in a Docker environment while ensuring seamless connectivity with an external Node.js service can be challenging. This article explores two key challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Connecting a Local Node.js Server as an External Host Machine with a Kafka Broker in Docker&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Understanding and Fixing Docker DNS Resolution Issues for Local Machine Communication&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We'll walk through the problems faced, their root causes, and step-by-step solutions.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Setting Up Kafka in a Docker Container&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We are using Bitnami's Kafka image, which supports KRaft mode (Kafka's built-in metadata management) without requiring ZooKeeper.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Create a Docker Network&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To ensure seamless communication between services, create a dedicated network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker network create app-tier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Run Kafka in KRaft Mode&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; kafka-server &lt;span class="nt"&gt;-p&lt;/span&gt; 9092:9092 &lt;span class="nt"&gt;--hostname&lt;/span&gt; kafka-server &lt;span class="se"&gt;\ &lt;/span&gt; 
    &lt;span class="nt"&gt;--network&lt;/span&gt; app-tier &lt;span class="se"&gt;\ &lt;/span&gt; 
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_CFG_NODE_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="se"&gt;\ &lt;/span&gt; 
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_CFG_PROCESS_ROLES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;controller,broker &lt;span class="se"&gt;\ &lt;/span&gt; 
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_CFG_LISTENERS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;PLAINTEXT://:9092,CONTROLLER://:9093 &lt;span class="se"&gt;\ &lt;/span&gt; 
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT &lt;span class="se"&gt;\ &lt;/span&gt; 
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_CFG_ADVERTISED_LISTENERS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;PLAINTEXT://192.168.1.10:9092 &lt;span class="se"&gt;\ &lt;/span&gt; 
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_CFG_CONTROLLER_QUORUM_VOTERS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0@kafka-server:9093 &lt;span class="se"&gt;\ &lt;/span&gt; 
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_CFG_CONTROLLER_LISTENER_NAMES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CONTROLLER &lt;span class="se"&gt;\ &lt;/span&gt; 
bitnami/kafka:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Understanding &lt;code&gt;advertised.listeners&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;listeners=PLAINTEXT://:9092&lt;/code&gt; → Kafka listens on all interfaces inside the container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;advertised.listeners=PLAINTEXT://192.168.1.10:9092&lt;/code&gt; → External clients connect using the &lt;strong&gt;host machine's IP&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This prevents Kafka from advertising its internal container IP, which would make it unreachable from the local machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Challenge 1: Connecting a Local Node.js Server to Docker Kafka&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;By default, a &lt;strong&gt;Docker container runs in an isolated network&lt;/strong&gt;. This means &lt;code&gt;localhost:9092&lt;/code&gt; inside the container does not refer to the host machine’s localhost. If a Node.js service runs outside Docker, it cannot connect to Kafka using &lt;code&gt;localhost:9092&lt;/code&gt; unless Kafka explicitly advertises the &lt;strong&gt;host machine's IP&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Solution: Use the Host IP&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Find your machine's IP address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip a | &lt;span class="nb"&gt;grep &lt;/span&gt;inet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, update Kafka’s &lt;code&gt;advertised.listeners&lt;/code&gt; to point to this IP.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Challenge 2: Docker DNS Resolution and Communication&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Even after setting the correct &lt;code&gt;advertised.listeners&lt;/code&gt;, issues may arise if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kafka and Node.js services are on different networks.&lt;/li&gt;
&lt;li&gt;Docker’s DNS resolution prevents local services from reaching Kafka.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Solution: Use Docker’s Built-in DNS&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Containers in the same network can resolve each other by name.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;kafka-server:9092&lt;/code&gt; &lt;strong&gt;inside Docker&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;192.168.1.10:9092&lt;/code&gt; &lt;strong&gt;outside Docker&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Fixing Docker Name Resolution for Node.js&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If your Node.js service runs &lt;strong&gt;inside a container&lt;/strong&gt;, ensure it is in the same network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker network connect app-tier nodejs-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kafka&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;Kafka&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cart.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;brokers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost:9092&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Final Working Node.js Kafka Integration&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Kafka Producer &amp;amp; Consumer Code&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Kafka&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Partitioners&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kafkajs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kafka&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;Kafka&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cart.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;brokers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost:9092&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;producer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;createPartitioner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Partitioners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DefaultPartitioner&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;groupId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cart.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;runConsumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cart.item.add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;eachMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Received message:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;runConsumer&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kafkaProducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;app&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/health-check&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/cart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;kafkaProducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cart.item.add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cart service is running on port 3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;By addressing &lt;strong&gt;Kafka’s networking challenges in Docker&lt;/strong&gt;, we ensured seamless communication between a local Node.js service and a Kafka broker running in a container. Key takeaways:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Use &lt;code&gt;advertised.listeners&lt;/code&gt; to expose Kafka correctly&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Leverage Docker DNS for intra-container communication&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Ensure Kafka and Node.js services are in communication with the docker container kafka broker&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@0_astrea?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Mélanie THESE&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/brown-and-blue-monkey-plush-toy-rz3eCYGgGSc?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>node</category>
      <category>docker</category>
      <category>dns</category>
    </item>
    <item>
      <title>🏗️ Building an Inventory Management System with Robust Error Handling in Node.js</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Fri, 14 Feb 2025 15:15:01 +0000</pubDate>
      <link>https://dev.to/rakshyak/building-an-inventory-management-system-with-robust-error-handling-in-nodejs-2g5i</link>
      <guid>https://dev.to/rakshyak/building-an-inventory-management-system-with-robust-error-handling-in-nodejs-2g5i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;🚀 Building a reliable inventory management system isn’t just about storing and retrieving data—it’s about ensuring your application gracefully handles errors. Imagine a customer trying to update inventory with negative stock or incorrect pricing. Without proper error handling, things could go very wrong! 😱&lt;/p&gt;

&lt;p&gt;In this guide, we’ll walk through a real-world CRUD implementation using Node.js, Express, and MongoDB, all while exploring best practices for error handling. And to make things fun, let’s check in with our two developers: &lt;strong&gt;Junior Dev 👶&lt;/strong&gt; and &lt;strong&gt;Senior Dev 🧙‍♂️&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  👶 Junior Dev: &lt;em&gt;“Why do I even need to handle errors? Can’t I just let the server explode?”&lt;/em&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  🧙‍♂️ Senior Dev: &lt;em&gt;“Sure, and then watch as your customers rage-quit your app! Let me show you how to do it right.”&lt;/em&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  🛠️ Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;First, let’s create our project and install the necessary dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;inventory-management
&lt;span class="nb"&gt;cd &lt;/span&gt;inventory-management
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;express mongoose dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  👶 Junior Dev: &lt;em&gt;“Done! Now what?”&lt;/em&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  🧙‍♂️ Senior Dev: &lt;em&gt;“Now we define the inventory model. And no, you can’t store ‘infinite’ items in your database.”&lt;/em&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  🏗️ Defining the Inventory Model
&lt;/h2&gt;

&lt;p&gt;Every inventory item needs a name, quantity, and price. To enforce data integrity, we define a schema with validation rules:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inventorySchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Inventory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Inventory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inventorySchema&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Inventory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  👶 Junior Dev: &lt;em&gt;“Wait, why do I need ‘min: 0’? Can’t I just check it later?”&lt;/em&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  🧙‍♂️ Senior Dev: &lt;em&gt;“Because catching bad data early means fewer fires to put out later! 🔥”&lt;/em&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  🚀 Setting Up the Express Server
&lt;/h2&gt;

&lt;p&gt;Our server will connect to MongoDB and handle API requests:&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="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inventoryRoutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./routes/inventory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/inventory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inventoryRoutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MONGO_URI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;useNewUrlParser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useUnifiedTopology&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🚀 Server running on port 3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;❌ Database connection error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  👶 Junior Dev: &lt;em&gt;“Cool! So if something breaks, the server just dies, right?”&lt;/em&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  🧙‍♂️ Senior Dev: &lt;em&gt;“NO! We handle errors properly. Let’s implement CRUD operations with structured error handling.”&lt;/em&gt; 😤
&lt;/h3&gt;




&lt;h2&gt;
  
  
  📝 Implementing CRUD Operations with Error Handling
&lt;/h2&gt;

&lt;h3&gt;
  
  
  API Routes (&lt;code&gt;routes/inventory.js&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Inventory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../models/Inventory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Custom Error Class&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValidationError&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ValidationError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create an Item&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&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="nc"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid input data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;item&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;Inventory&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;handleErrors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Centralized Error Handling Function&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleErrors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Internal Server Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  👶 Junior Dev: &lt;em&gt;“Why do we need this fancy error class? Can’t I just console.log errors?”&lt;/em&gt; 🤔
&lt;/h3&gt;

&lt;h3&gt;
  
  
  🧙‍♂️ Senior Dev: &lt;em&gt;“If you do that, debugging production errors will be a nightmare! This way, we categorize issues properly.”&lt;/em&gt; 🎯
&lt;/h3&gt;




&lt;h2&gt;
  
  
  💡 Why This Approach Works
&lt;/h2&gt;

&lt;p&gt;Handling errors properly improves reliability and usability. Here’s how we achieve that:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Prevention First&lt;/strong&gt; – Validate data before it enters the database.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Clear Error Messages&lt;/strong&gt; – Users get meaningful errors instead of cryptic system messages.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Custom Error Handling&lt;/strong&gt; – Distinguish between validation errors and system errors.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Consistent API Responses&lt;/strong&gt; – Every response follows the same structured format.&lt;/p&gt;




&lt;h3&gt;
  
  
  👶 Junior Dev: &lt;em&gt;“Alright, I see the point. But what happens when I forget to handle an error?”&lt;/em&gt; 😬
&lt;/h3&gt;

&lt;h3&gt;
  
  
  🧙‍♂️ Senior Dev: &lt;em&gt;“That’s when production crashes at 2 AM, and your phone won’t stop ringing.”&lt;/em&gt; 📞🔥
&lt;/h3&gt;




&lt;h2&gt;
  
  
  🎯 Wrapping Up
&lt;/h2&gt;

&lt;p&gt;A well-structured inventory management system isn’t just about CRUD operations—it’s about making sure errors are handled smartly. This makes your application more resilient and easier to maintain.&lt;/p&gt;

&lt;p&gt;Start integrating these techniques into your projects today, and you’ll write cleaner, more professional code. And remember—&lt;strong&gt;always handle errors before they handle you!&lt;/strong&gt; ⚡&lt;/p&gt;




&lt;h3&gt;
  
  
  👶 Junior Dev: &lt;em&gt;“Thanks, sensei! Now I won’t fear errors anymore.”&lt;/em&gt; 😎
&lt;/h3&gt;

&lt;h3&gt;
  
  
  🧙‍♂️ Senior Dev: &lt;em&gt;“Good. Now go forth and build error-free apps… or at least fewer 500 errors.”&lt;/em&gt; 😉
&lt;/h3&gt;




&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@soberanes?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Uriel Soberanes&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/man-wearing-sony-playstation-vr-MxVkWPiJALs?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>express</category>
      <category>nodeerror</category>
    </item>
    <item>
      <title>design pattern in react</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Fri, 31 Jan 2025 10:10:54 +0000</pubDate>
      <link>https://dev.to/rakshyak/design-pattern-in-react-36fd</link>
      <guid>https://dev.to/rakshyak/design-pattern-in-react-36fd</guid>
      <description></description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>designpatterns</category>
    </item>
    <item>
      <title>Avoiding State Inconsistencies: The Pitfall of Multiple React Context Providers</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Fri, 31 Jan 2025 09:56:40 +0000</pubDate>
      <link>https://dev.to/rakshyak/avoiding-state-inconsistencies-the-pitfall-of-multiple-react-context-providers-4e29</link>
      <guid>https://dev.to/rakshyak/avoiding-state-inconsistencies-the-pitfall-of-multiple-react-context-providers-4e29</guid>
      <description>&lt;h2&gt;
  
  
  The Hidden Pitfall of Using Multiple Context Providers in React
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;React Context API is a powerful tool for managing state across components. However, a common mistake developers make is wrapping different sections of their app with separate instances of the same Context Provider, leading to unexpected behavior.&lt;/p&gt;

&lt;p&gt;In this post, we’ll explore why this happens, its impact, and the correct way to use Context to avoid these pitfalls.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mistake: Multiple Instances of the Same Provider
&lt;/h2&gt;

&lt;p&gt;Consider this React component structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CartProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Navbar&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CartProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-4xl font-semibold mt-20"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Products&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CartProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex gap-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Products&lt;/span&gt; &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* &amp;lt;Cart /&amp;gt; */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CartProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this looks fine. But there’s a major issue: &lt;strong&gt;each &lt;code&gt;&amp;lt;CartProvider&amp;gt;&lt;/code&gt; creates a new, separate context instance.&lt;/strong&gt; This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Navbar&lt;/code&gt; is inside the first &lt;code&gt;&amp;lt;CartProvider&amp;gt;&lt;/code&gt;, while &lt;code&gt;Products&lt;/code&gt; is inside another.&lt;/li&gt;
&lt;li&gt;When &lt;code&gt;Products&lt;/code&gt; updates the cart, the change is only reflected inside its provider.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Navbar&lt;/code&gt;, wrapped in a separate provider, does not see these updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This results in an inconsistent UI, where the cart count in the &lt;code&gt;Navbar&lt;/code&gt; does not update when products are added.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Happens
&lt;/h2&gt;

&lt;p&gt;React Context works by creating a &lt;strong&gt;Provider&lt;/strong&gt; that passes state down to its children. However, &lt;strong&gt;each Provider instance manages its own independent state&lt;/strong&gt;. When you wrap different sections of your UI in separate &lt;code&gt;&amp;lt;CartProvider&amp;gt;&lt;/code&gt; components, they function as isolated stores rather than a shared state.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Context Providers Work Internally
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Each &lt;code&gt;&amp;lt;CartProvider&amp;gt;&lt;/code&gt; creates its own state using &lt;code&gt;useState&lt;/code&gt; or &lt;code&gt;useReducer&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The context value (&lt;code&gt;cart, setCart&lt;/code&gt;) is unique to that instance.&lt;/li&gt;
&lt;li&gt;Consumers (&lt;code&gt;useContext(CartContext)&lt;/code&gt;) only receive updates from the nearest provider.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thus, if you have two providers, &lt;strong&gt;they do not share state&lt;/strong&gt;, leading to desynchronized data across components.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Correct Approach: A Single Context Provider
&lt;/h2&gt;

&lt;p&gt;To ensure all components share the same state, wrap the &lt;strong&gt;entire&lt;/strong&gt; app (or the relevant section) inside &lt;strong&gt;one&lt;/strong&gt; &lt;code&gt;&amp;lt;CartProvider&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CartProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Navbar&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-4xl font-semibold mt-20"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Products&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex gap-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Products&lt;/span&gt; &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* &amp;lt;Cart /&amp;gt; */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CartProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why This Works
&lt;/h3&gt;

&lt;p&gt;✔️ &lt;strong&gt;Single source of truth:&lt;/strong&gt; All components access the same &lt;code&gt;CartContext&lt;/code&gt; instance.&lt;br&gt;
✔️ &lt;strong&gt;State updates propagate correctly:&lt;/strong&gt; When &lt;code&gt;Products&lt;/code&gt; updates the cart, &lt;code&gt;Navbar&lt;/code&gt; reflects the changes.&lt;br&gt;
✔️ &lt;strong&gt;Better performance:&lt;/strong&gt; Reduces unnecessary re-renders from multiple context providers.&lt;br&gt;
✔️ &lt;strong&gt;Easier debugging:&lt;/strong&gt; Avoids confusion caused by desynchronized states.&lt;/p&gt;


&lt;h2&gt;
  
  
  How to Detect This Issue in Your App
&lt;/h2&gt;

&lt;p&gt;If you suspect multiple context providers are causing state inconsistencies, try these debugging steps:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Log the Context Value
&lt;/h3&gt;

&lt;p&gt;Add a &lt;code&gt;console.log&lt;/code&gt; inside a component consuming the context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CartContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cart context: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see multiple logs with different values, you likely have multiple providers.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Use React DevTools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open &lt;strong&gt;React Developer Tools&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Look for multiple &lt;code&gt;&amp;lt;CartProvider&amp;gt;&lt;/code&gt; instances.&lt;/li&gt;
&lt;li&gt;Check if different components are consuming different instances.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Using multiple instances of the same Context Provider in different sections of your app &lt;strong&gt;breaks state synchronization&lt;/strong&gt;. To avoid this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use a single provider&lt;/strong&gt; for globally shared state.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ensure all consumers are wrapped under the same provider.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use debugging tools&lt;/strong&gt; to detect multiple providers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By structuring your Context usage correctly, you ensure a predictable, seamless state management experience in your React applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Have you faced issues with React Context before? Share your experience in the comments!
&lt;/h2&gt;

&lt;p&gt;say thanks for the image &lt;a href="https://pixabay.com/users/richardsdrawings-858383/" rel="noopener noreferrer"&gt;RichardsDrawings&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>contextprovider</category>
    </item>
    <item>
      <title>Understanding Stream Methods in Node.js: A Guide to `read` and `write`</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Sat, 16 Nov 2024 05:50:18 +0000</pubDate>
      <link>https://dev.to/rakshyak/understanding-stream-methods-in-nodejs-a-guide-to-read-and-write-gn7</link>
      <guid>https://dev.to/rakshyak/understanding-stream-methods-in-nodejs-a-guide-to-read-and-write-gn7</guid>
      <description>&lt;p&gt;Node.js provides powerful stream capabilities that allow developers to handle data efficiently. By utilizing stream methods like &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; alongside event listeners, developers can effectively consume streams. This article will delve into the mechanics of streams, focusing on the interplay between readable and writable streams, backpressure management, and error handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stream Basics
&lt;/h2&gt;

&lt;p&gt;In Node.js, streams are objects that facilitate reading and writing data in a continuous manner. They can be classified into four types: readable, writable, duplex (both readable and writable), and transform (a type of duplex stream that can modify data as it is read or written).&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of Using &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The following code snippet demonstrates how to use readable and writable streams together:&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="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&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;The &lt;code&gt;data&lt;/code&gt; event is emitted when there is data available to read from the &lt;code&gt;readable&lt;/code&gt; stream. Each chunk of data is written to the &lt;code&gt;writable&lt;/code&gt; stream.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;end&lt;/code&gt; event signifies that there are no more data chunks to read, prompting the writable stream to end.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding Stream Pressure
&lt;/h2&gt;

&lt;p&gt;The rate at which data flows through a stream is referred to as &lt;strong&gt;pressure&lt;/strong&gt;. When a writable stream processes data at a slower rate than a readable stream pushes data, it leads to &lt;strong&gt;backpressure&lt;/strong&gt;. This situation occurs when the writable stream's buffer fills up, causing it to temporarily stop accepting new data until it can process the buffered data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handling Backpressure
&lt;/h3&gt;

&lt;p&gt;When managing backpressure, it's crucial to check the return value of the &lt;code&gt;write&lt;/code&gt; method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the writable stream can accept more data, &lt;code&gt;write&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the memory limit is reached, it returns &lt;code&gt;false&lt;/code&gt;, indicating that further writes should pause until the &lt;code&gt;drain&lt;/code&gt; event is emitted.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Stop reading from the readable stream until drain event&lt;/span&gt;
    &lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;drain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Resume reading from the readable stream&lt;/span&gt;
    &lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Error Handling in Streams
&lt;/h2&gt;

&lt;p&gt;Streams can emit errors at any time, making it essential to handle them properly. This is particularly important when using the &lt;code&gt;pipe&lt;/code&gt; method, which automatically manages data flow between streams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of Error Handling
&lt;/h3&gt;

&lt;p&gt;Here’s how you can handle errors for both readable and writable streams:&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="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Read error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Write error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By listening for the &lt;code&gt;error&lt;/code&gt; event on both streams, you ensure that any issues encountered during reading or writing are appropriately managed.&lt;/p&gt;




</description>
      <category>stream</category>
      <category>node</category>
      <category>backpressure</category>
    </item>
    <item>
      <title>Why Developers Choose Databases Over File Storage for Scalable Data Management💾 ➡️ 🗄️</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Sun, 03 Nov 2024 08:26:27 +0000</pubDate>
      <link>https://dev.to/rakshyak/why-developers-choose-databases-over-file-storage-for-scalable-data-management-2h7n</link>
      <guid>https://dev.to/rakshyak/why-developers-choose-databases-over-file-storage-for-scalable-data-management-2h7n</guid>
      <description>&lt;p&gt;As data grows, developers often shift from simple file storage to databases. Let’s dive into why databases make managing data easier and more reliable for coding projects.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Data Consistency and ACID Compliance 🔄
&lt;/h3&gt;

&lt;p&gt;Most databases are &lt;strong&gt;ACID-compliant&lt;/strong&gt; (Atomicity, Consistency, Isolation, Durability), meaning they provide reliable data handling, which is challenging with file storage.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fact:&lt;/strong&gt; ACID compliance allows a database to handle billions of transactions daily without errors. Many financial services rely on ACID compliance to ensure accuracy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Indexing for Faster Data Retrieval 📈
&lt;/h3&gt;

&lt;p&gt;Databases have built-in &lt;strong&gt;indexing&lt;/strong&gt; to speed up data retrieval by creating optimized access paths.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fact:&lt;/strong&gt; Indexing can improve query speeds by over &lt;strong&gt;100x&lt;/strong&gt; in large datasets. Without indexing, complex searches on millions of entries would take hours instead of seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Concurrency Control for Multi-User Access 👥
&lt;/h3&gt;

&lt;p&gt;Databases offer &lt;strong&gt;concurrent access&lt;/strong&gt; features, allowing multiple users or processes to interact with data simultaneously.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fact:&lt;/strong&gt; Databases like PostgreSQL and MySQL support thousands of simultaneous users, thanks to concurrency control mechanisms, ensuring data integrity under heavy loads.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Optimized Storage and Query Processing 🗃️
&lt;/h3&gt;

&lt;p&gt;Databases store data in optimized formats (e.g., binary storage, columnar storage for analytics), which allows for fast retrieval and efficient use of storage.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fact:&lt;/strong&gt; Columnar databases, popular in data analytics, can reduce storage by up to &lt;strong&gt;90%&lt;/strong&gt; and accelerate aggregation queries by processing only necessary columns.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. SQL for Flexible Data Queries 📝
&lt;/h3&gt;

&lt;p&gt;SQL provides &lt;strong&gt;flexible, powerful commands&lt;/strong&gt; to quickly search, update, and analyze data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fact:&lt;/strong&gt; SQL, invented in the 1970s, is still the dominant query language for databases. Around &lt;strong&gt;80% of data management jobs&lt;/strong&gt; list SQL as a required skill due to its efficiency in handling complex data operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Automated Data Integrity and Constraints ✅
&lt;/h3&gt;

&lt;p&gt;Databases enforce &lt;strong&gt;constraints&lt;/strong&gt; (like primary keys and unique constraints) to maintain data relationships and integrity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fact:&lt;/strong&gt; In MySQL, constraints reduce coding errors and increase database reliability, enabling developers to store millions of unique values without duplicates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7. Built-in Backup, Replication, and Recovery 🔄
&lt;/h3&gt;

&lt;p&gt;Database systems come with &lt;strong&gt;automated backup, replication, and recovery&lt;/strong&gt; options, ensuring high availability and data safety.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fact:&lt;/strong&gt; Many databases support &lt;strong&gt;replication&lt;/strong&gt;, creating multiple synchronized copies of data across locations to prevent data loss and reduce downtime, which is crucial for business continuity.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;For developers, databases offer &lt;strong&gt;reliable performance, reduced coding complexity, and scalability&lt;/strong&gt;—all critical for data-intensive applications in a coding environment.&lt;/p&gt;

</description>
      <category>database</category>
      <category>filestorage</category>
    </item>
    <item>
      <title>How SSH-Agent Transforms SSH Authentication into a Breeze</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Sat, 12 Oct 2024 16:01:04 +0000</pubDate>
      <link>https://dev.to/rakshyak/how-ssh-agent-transforms-ssh-authentication-into-a-breeze-4gcj</link>
      <guid>https://dev.to/rakshyak/how-ssh-agent-transforms-ssh-authentication-into-a-breeze-4gcj</guid>
      <description>&lt;p&gt;🤔 "SSH-Agent: Because typing your passphrase every time is so 2001!"&lt;/p&gt;

&lt;h4&gt;
  
  
  What is SSH-Agent?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSH-Agent&lt;/strong&gt; is a utility that securely manages your SSH keys and automates the authentication process for SSH connections. It eliminates the need to type in your passphrase each time you connect to a server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Example: Setting Up SSH-Agent for Accessing a Remote Server
&lt;/h3&gt;

&lt;p&gt;Let’s walk through the exact steps to configure &lt;strong&gt;SSH-Agent&lt;/strong&gt; on a local machine (Linux/macOS) and connect to a remote server using a private key.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. &lt;strong&gt;Generate an SSH Key Pair (If You Don't Have One)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before using SSH-Agent, you need to create an SSH key pair (public and private). Here’s how you can do that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open your terminal&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Run this command to create a new key pair:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"your_email@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Press &lt;strong&gt;Enter&lt;/strong&gt; to accept the default file location (&lt;code&gt;~/.ssh/id_rsa&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Set a strong passphrase (optional but recommended) for your private key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will create two files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;id_rsa&lt;/code&gt; (your private key)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;id_rsa.pub&lt;/code&gt; (your public key)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Start the SSH-Agent&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that your SSH key is created, let’s start the SSH-Agent.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the following command in your terminal to start the agent:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;ssh-agent &lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start the SSH agent and display the agent's process ID.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Add Your Private Key to the SSH-Agent&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Next, you’ll add the private key to the agent so it can be used for authentication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the private key to the SSH-Agent:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-add ~/.ssh/id_rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be prompted for the passphrase you set earlier (if you set one).&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Copy Your Public Key to the Remote Server&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You need to place your public key on the remote server where you want to connect. Here’s a simple way to do that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the &lt;code&gt;ssh-copy-id&lt;/code&gt; command to copy your public key:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-copy-id user@remote-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;user&lt;/code&gt; with your remote server’s username and &lt;code&gt;remote-server&lt;/code&gt; with the server's IP address or hostname.&lt;/p&gt;

&lt;p&gt;You may be prompted to enter the password for the remote user. Once this is done, the server will have your public key, and you can authenticate using your private key.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Connect to the Remote Server Using SSH&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now you can SSH into the remote server without typing the passphrase every time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh user@remote-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SSH-Agent will automatically use the private key stored in memory for authentication.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. &lt;strong&gt;Forwarding Your SSH-Agent (Optional)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you need to access another server from the first one, you can forward your SSH keys. This means the remote server will use your local machine's SSH-Agent.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To enable forwarding, simply add the &lt;code&gt;-A&lt;/code&gt; flag when connecting:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-A&lt;/span&gt; user@remote-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that the keys are forwarded to the remote machine.&lt;/p&gt;




&lt;h3&gt;
  
  
  Summary of Commands
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate SSH Key&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"your_email@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start SSH-Agent&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;ssh-agent &lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Add Private Key&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh-add ~/.ssh/id_rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Copy Public Key to Remote Server&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh-copy-id user@remote-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SSH into Remote Server&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh user@remote-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SSH with Key Forwarding (Optional)&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh &lt;span class="nt"&gt;-A&lt;/span&gt; user@remote-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;SSH-Agent is like your personal valet for remote server connections—it takes care of the key authentication so you don’t have to. No more typing in your passphrase every time you SSH into a server! This guide will walk you through setting it up, and before you know it, you’ll be breezing through connections like a pro.&lt;/p&gt;

&lt;p&gt;Fun Fact: Did you know that SSH (Secure Shell) was originally developed in 1995 as a secure way to replace old, insecure protocols? And now, thanks to SSH-Agent, we don’t even have to think about it! 😎&lt;/p&gt;

</description>
      <category>remoteaccess</category>
      <category>keybasedauthentication</category>
      <category>serverauthentication</category>
      <category>secureconnections</category>
    </item>
    <item>
      <title>Data Manipulation with Strings and Arrays in Bash</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Sun, 06 Oct 2024 17:17:11 +0000</pubDate>
      <link>https://dev.to/rakshyak/data-manipulation-with-strings-and-arrays-in-bash-n4h</link>
      <guid>https://dev.to/rakshyak/data-manipulation-with-strings-and-arrays-in-bash-n4h</guid>
      <description>&lt;p&gt;When it comes to data manipulation in &lt;strong&gt;Bash&lt;/strong&gt;, there’s a broad array of techniques that you can apply, building on foundational skills. This post will explore practical approaches to manipulating data structures like &lt;strong&gt;arrays&lt;/strong&gt; and &lt;strong&gt;strings&lt;/strong&gt; using &lt;strong&gt;Bash&lt;/strong&gt;. It also covers some advanced techniques such as parsing character-delimited records, reading data files, and using Bash’s parameter expansion to manipulate data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Concepts Covered:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Arrays&lt;/strong&gt; in Bash&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parameter Expansion&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parsing Data with Character Delimiters&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reading Data Files&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Functions for Two-Dimensional Grids&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sorting and Searching Arrays&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What you will from this:
&lt;/h3&gt;

&lt;p&gt;Data manipulation in Bash, particularly with strings and arrays, offers flexibility in handling structured and unstructured data. From parsing character-delimited records to simulating two-dimensional grids, the power of Bash scripting comes from its ability to handle various data types efficiently.&lt;/p&gt;

&lt;p&gt;These techniques can help you create &lt;strong&gt;robust&lt;/strong&gt; Bash scripts to automate data manipulation tasks. For freshers, mastering these concepts can help in building a strong foundation for more complex automation scripts.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Arrays in Bash
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Arrays&lt;/strong&gt; are essential in Bash scripting, allowing you to store and manipulate lists of values efficiently. While you may already know the basic syntax (covered in &lt;strong&gt;Chapter 5&lt;/strong&gt;), it’s time to dive deeper into their uses for handling more complex data.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Declaring an array&lt;/span&gt;
&lt;span class="nv"&gt;my_array&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;apple orange banana&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Accessing array elements&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;my_array&lt;/span&gt;&lt;span class="p"&gt;[1]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;   &lt;span class="c"&gt;# Outputs: orange&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Arrays can store lists of data, making them useful for organizing and processing sequences of items.&lt;/p&gt;

&lt;h4&gt;
  
  
  Advantages of Arrays:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Easy to store&lt;/strong&gt; multiple values&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster&lt;/strong&gt; data manipulation in sequential operations&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Disadvantages:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Limited&lt;/strong&gt; to numerical indices (can’t use keys like in dictionaries)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lacks complex&lt;/strong&gt; data structures like other programming languages&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Parameter Expansion for Data Parsing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Parameter expansion&lt;/strong&gt; offers many ways to manipulate strings and arrays in Bash, such as slicing, substitution, and removing patterns. Though used across many Bash scripts, it’s crucial for data parsing, especially when handling &lt;strong&gt;character-delimited&lt;/strong&gt; data.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Splitting a String by Delimiters
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"apple,orange,banana"&lt;/span&gt;
&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; array &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$string&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Outputs each element in the array&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;element &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$element&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach splits a comma-separated string into an array, a common scenario when dealing with &lt;strong&gt;CSV&lt;/strong&gt; or other delimited data files.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Parsing Character-Delimited Records
&lt;/h3&gt;

&lt;p&gt;When dealing with data structured as character-delimited records (e.g., &lt;strong&gt;CSV&lt;/strong&gt;), parsing them into individual fields allows for easier processing. Arrays and loops in Bash make this task simple.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Parsing CSV Data
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; col1 col2 col3&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Col1: &lt;/span&gt;&lt;span class="nv"&gt;$col1&lt;/span&gt;&lt;span class="s2"&gt;, Col2: &lt;/span&gt;&lt;span class="nv"&gt;$col2&lt;/span&gt;&lt;span class="s2"&gt;, Col3: &lt;/span&gt;&lt;span class="nv"&gt;$col3&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt; &amp;lt; file.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reads each line in a CSV file and splits it into separate columns, which can be manipulated as individual fields.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Reading Data Files in Bash
&lt;/h3&gt;

&lt;p&gt;One common use of Bash is processing data from files. Whether you are reading structured data like &lt;strong&gt;CSV&lt;/strong&gt; files or unstructured text, understanding how to read and process files is a must.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Reading a File Line by Line
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; line&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$line&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt; &amp;lt; file.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This loop reads each line of a file, making it useful for file parsing and manipulation.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Functions for Two-Dimensional Grids
&lt;/h3&gt;

&lt;p&gt;Manipulating two-dimensional data structures like tables or grids can be done using arrays of arrays. Though Bash doesn’t natively support two-dimensional arrays, you can simulate them using associative arrays or nested arrays.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Simulating 2D Array
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;declare&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; matrix
matrix[0,0]&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"apple"&lt;/span&gt;
matrix[0,1]&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"orange"&lt;/span&gt;
matrix[1,0]&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banana"&lt;/span&gt;
matrix[1,1]&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"grape"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[0,1]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;  &lt;span class="c"&gt;# Outputs: orange&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  6. Sorting and Searching Arrays
&lt;/h3&gt;

&lt;p&gt;For &lt;strong&gt;sorting&lt;/strong&gt; and &lt;strong&gt;searching&lt;/strong&gt; arrays, Bash provides utilities like &lt;code&gt;sort&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; which allow you to manipulate data quickly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Sorting an Array
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;my_array&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;banana apple grape orange&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;sorted_array&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;my_array&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;sorted_array&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;  &lt;span class="c"&gt;# Outputs: apple banana grape orange&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Searching an Array
&lt;/h4&gt;

&lt;p&gt;You can search arrays for specific elements using loops or &lt;code&gt;grep&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;my_array&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;~ &lt;span class="s2"&gt;" apple "&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Apple found!"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






</description>
      <category>bash</category>
      <category>dataprocessing</category>
      <category>script</category>
    </item>
    <item>
      <title>GitHub Workflow and Automation: Streamlining Project Management 🚀</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Sun, 29 Sep 2024 16:12:16 +0000</pubDate>
      <link>https://dev.to/rakshyak/github-workflow-and-automation-streamlining-project-management-57h8</link>
      <guid>https://dev.to/rakshyak/github-workflow-and-automation-streamlining-project-management-57h8</guid>
      <description>&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;While GitHub offers powerful workflow automation for free, surprisingly, only a small percentage of users take full advantage of it. Despite this, the learning curve is minimal, and GitHub has made the integration of workflows straightforward, even for beginners. By using workflows effectively, teams can automate repetitive tasks, streamline project management, and improve productivity without additional cost. 🌟&lt;/p&gt;




&lt;h3&gt;
  
  
  How to Automate with GitHub Actions
&lt;/h3&gt;

&lt;p&gt;GitHub Actions enables you to automate your workflows based on specific events in your repository. Here’s how to get started:&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Create a GitHub Action
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to your repository on GitHub.&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Actions&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Choose a template or click on &lt;strong&gt;set up a workflow yourself&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 2: Define Your Workflow
&lt;/h4&gt;

&lt;p&gt;Create a YAML file (e.g., &lt;code&gt;main.yml&lt;/code&gt;) in the &lt;code&gt;.github/workflows&lt;/code&gt; directory of your repository. Here’s a simple example:&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&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;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&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;This workflow runs on every push to the &lt;code&gt;main&lt;/code&gt; branch.&lt;/li&gt;
&lt;li&gt;It checks out the code using the &lt;code&gt;checkout&lt;/code&gt; action.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.github.com/en/actions" rel="noopener noreferrer"&gt;For more help on setting up GitHub Actions, click here.&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Using Webhooks for Automation
&lt;/h3&gt;

&lt;p&gt;Webhooks allow you to send real-time data from one application to another whenever an event occurs. Here’s how to set up a Webhook in your GitHub repository:&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Create a Webhook
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Go to your repository settings.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Webhooks&lt;/strong&gt; in the sidebar.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Add webhook&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 2: Configure the Webhook
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Payload URL:&lt;/strong&gt; Enter the URL where you want to receive the webhook payload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content type:&lt;/strong&gt; Select &lt;code&gt;application/json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which events would you like to trigger this webhook?&lt;/strong&gt; Choose the events that trigger the webhook (e.g., &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;issues&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example Webhook JSON Payload:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"opened"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Issue Title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Issue body content"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&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;This payload is sent when an issue is opened, containing details about the issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.github.com/en/developers/webhooks" rel="noopener noreferrer"&gt;For detailed instructions on setting up Webhooks, click here.&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Focus on GitHub Project Feature Integration
&lt;/h3&gt;

&lt;p&gt;GitHub Projects allow you to manage your work with Kanban-style boards. Here’s how to integrate an automation workflow with GitHub Projects.&lt;/p&gt;

&lt;h4&gt;
  
  
  Automation Workflow
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Creating a Task Template in "To Do" Column:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;When someone creates a task in the "To Do" column, automate the generation of a task template. This template will include:

&lt;ul&gt;
&lt;li&gt;References for the task&lt;/li&gt;
&lt;li&gt;Specific requirements&lt;/li&gt;
&lt;li&gt;Author name&lt;/li&gt;
&lt;li&gt;File attachments&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can use GitHub Actions to achieve this. An example YAML configuration might look like this:&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create Task Template&lt;/span&gt;

   &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;project_card&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;created&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;moved&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

   &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;create_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
       &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create Template&lt;/span&gt;
           &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Create your template here!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Creating an Issue and Branch in "In Progress" Column:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When someone moves a task to the "In Progress" column, automate the creation of a new issue and branch. The issue title will be the task title, and the branch name follows this convention:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; feature-{date of issue created}/issue-title-{issue number}
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example workflow snippet for creating an issue might be:&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create Issue and Branch&lt;/span&gt;

   &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;project_card&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;moved&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;To&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Do"&lt;/span&gt;
         &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;In&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Progress"&lt;/span&gt;

   &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;create_issue_and_branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
       &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create Issue&lt;/span&gt;
           &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
             &lt;span class="s"&gt;echo "Create issue with title ${{ github.event.project_card.note }}"&lt;/span&gt;
             &lt;span class="s"&gt;echo "Create branch with naming convention"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Understanding and utilizing GitHub workflows can significantly enhance your project management capabilities. By automating tasks and integrating features like GitHub Actions and Webhooks, you can streamline your development process efficiently. As a fellow developer, I encourage freshers to explore these tools and reach out with any questions or for guidance. 🌟🚀&lt;/p&gt;




</description>
      <category>github</category>
      <category>workflow</category>
      <category>actions</category>
      <category>automation</category>
    </item>
    <item>
      <title>Understanding How Your OS Handles Print Requests to the Console 🖥️</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Fri, 27 Sep 2024 15:40:08 +0000</pubDate>
      <link>https://dev.to/rakshyak/understanding-how-your-os-handles-print-requests-to-the-console-3nmp</link>
      <guid>https://dev.to/rakshyak/understanding-how-your-os-handles-print-requests-to-the-console-3nmp</guid>
      <description>&lt;p&gt;When you run a program and ask it to print something to the console, have you ever wondered what happens behind the scenes? 🤔 In this post, we’ll dive into the fascinating world of standard output (stdout) and how your operating system (OS) manages these requests. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Standard Output? 📢
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Standard Output (stdout)&lt;/strong&gt; is a predefined channel through which programs send their output data. It’s like a direct line to your console or terminal, allowing you to see results, messages, and more. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;File Descriptor&lt;/strong&gt;: In most systems, stdout is represented by the file descriptor &lt;code&gt;1&lt;/code&gt;. In C programming, it’s represented by &lt;code&gt;FILE* stdout&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Use Standard Output?
&lt;/h3&gt;

&lt;p&gt;Using stdout allows programmers to communicate with users effectively. It separates regular output from error messages, making it easier to debug applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does the OS Handle Output Requests? ⚙️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Buffering: The Efficiency Booster 🚀
&lt;/h3&gt;

&lt;p&gt;When you print something, the OS doesn’t immediately send it to the console. Instead, it uses &lt;strong&gt;buffering&lt;/strong&gt; to improve performance. By default:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Line-buffered&lt;/strong&gt;: In interactive environments (like terminals), data is sent when a newline character (&lt;code&gt;\n&lt;/code&gt;) is encountered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flushing&lt;/strong&gt;: You can manually flush the buffer to force output to appear immediately.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Example in C:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, World!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// This will be buffered until the newline.&lt;/span&gt;
    &lt;span class="n"&gt;fflush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Forces the buffer to flush.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example in Python:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, World!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Automatically flushed when a newline is printed.
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# Manually flushes stdout if needed.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Redirection: Flexibility at Its Best 🔄
&lt;/h3&gt;

&lt;p&gt;One of the powerful features of stdout is its ability to be redirected. This means you can send output not just to the console but also to files or other devices.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to Redirect Output:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In the Terminal&lt;/strong&gt;: You can run your program and redirect output like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ./your_program &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; output.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command sends all stdout data to &lt;code&gt;output.txt&lt;/code&gt; instead of displaying it on the console.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Error Handling: Keeping Things Separate ⚠️
&lt;/h3&gt;

&lt;p&gt;Alongside stdout, there’s also &lt;strong&gt;Standard Error (stderr)&lt;/strong&gt; for error messages. Stderr operates similarly but is typically unbuffered. This means that error messages appear immediately, even if stdout is redirected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: The Magic Behind Printing 🎩✨
&lt;/h2&gt;

&lt;p&gt;When you request a print in your program, the OS plays a crucial role in managing that request through standard streams. By understanding how stdout works—through buffering, redirection, and error handling—you can write more efficient and user-friendly applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources for Further Learning 📚
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C Programming Language&lt;/strong&gt;: &lt;a href="https://www.learn-c.org/" rel="noopener noreferrer"&gt;Learn C&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python Documentation&lt;/strong&gt;: &lt;a href="https://docs.python.org/3/tutorial/inputoutput.html" rel="noopener noreferrer"&gt;Python Official Docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unix/Linux Redirection&lt;/strong&gt;: &lt;a href="https://linuxcommand.org/lc3_adv_redirection.php" rel="noopener noreferrer"&gt;Linux Command Line&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to explore these resources and enhance your understanding of standard output and its management by the operating system!&lt;/p&gt;

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

</description>
      <category>linux</category>
      <category>process</category>
      <category>buffer</category>
      <category>operatingsystem</category>
    </item>
    <item>
      <title>Unlocking the Power of Git Worktree: A Game-Changer for Developers 🚀</title>
      <dc:creator>Rakshyak Satpathy</dc:creator>
      <pubDate>Thu, 19 Sep 2024 17:54:04 +0000</pubDate>
      <link>https://dev.to/rakshyak/unlocking-the-power-of-git-worktree-a-game-changer-for-developers-5b32</link>
      <guid>https://dev.to/rakshyak/unlocking-the-power-of-git-worktree-a-game-changer-for-developers-5b32</guid>
      <description>&lt;p&gt;As developers, we often find ourselves juggling multiple branches, features, and bug fixes. Enter &lt;strong&gt;Git Worktree&lt;/strong&gt;—a feature that has transformed the way I manage my projects and has the potential to do the same for you! Here’s a deep dive into what I’ve learned about this incredible tool and how it can elevate your Git game.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌳 What is Git Worktree?
&lt;/h3&gt;

&lt;p&gt;Imagine being able to work on multiple branches simultaneously without the hassle of constantly switching contexts or worrying about conflicts. Git Worktree allows you to create additional working trees linked to a single repository. This means you can have separate directories for different branches, all while sharing the same underlying Git database. It’s like having multiple branches of a tree, each flourishing in its own space!&lt;/p&gt;

&lt;h3&gt;
  
  
  🔄 Seamless Branch Switching
&lt;/h3&gt;

&lt;p&gt;One of the standout features of Git Worktree is the ability to switch between branches effortlessly. Instead of waiting for lengthy checkouts or risking merge conflicts, you can simply create a new worktree for each branch. Here’s how to do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start by creating a new branch&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/new-awesome-feature

&lt;span class="c"&gt;# Now create a worktree for another branch&lt;/span&gt;
git worktree add ../new-feature-worktree feature/new-awesome-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can navigate to &lt;code&gt;../new-feature-worktree&lt;/code&gt; and start working on your feature without interrupting your main development flow!&lt;/p&gt;

&lt;h3&gt;
  
  
  💾 Save Space, Stay Efficient
&lt;/h3&gt;

&lt;p&gt;Worried about disk space? Fear not! Since all worktrees share the same object database, you won’t be duplicating data unnecessarily. This makes Git Worktree not only efficient but also a great option for those working on larger projects where every megabyte counts.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠️ Streamline Your Workflow
&lt;/h3&gt;

&lt;p&gt;Imagine being able to run tests on one branch while developing features on another—all without any interruptions. With Git Worktree, this becomes a reality. You can easily rebase, merge, and push changes independently in each worktree. Here’s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In your main worktree, let's say you're on the main branch&lt;/span&gt;
git checkout main

&lt;span class="c"&gt;# Meanwhile, in your new worktree for the feature branch&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ../new-feature-worktree
&lt;span class="c"&gt;# Make changes and commit them&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Implement new awesome feature"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flexibility allows you to maintain focus and productivity, no matter how complex your project becomes.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 A Learning Playground
&lt;/h3&gt;

&lt;p&gt;Git Worktree isn’t just a productivity tool; it’s also an excellent learning resource. By creating worktrees for different branches or commits, you can experiment freely without fear of messing up your main project. Want to see how a feature evolved? Jump into its worktree and explore! &lt;/p&gt;

&lt;p&gt;For instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a worktree from an older commit to analyze changes&lt;/span&gt;
git worktree add ../old-version-worktree &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This hands-on approach deepens your understanding of Git and enhances your coding skills.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌟 Why You Should Try It
&lt;/h3&gt;

&lt;p&gt;If you haven’t yet explored Git Worktree, I encourage you to give it a shot! Not only will it simplify your workflow, but it will also open up new avenues for collaboration and experimentation. Whether you’re tackling a complex project or just want to streamline your daily tasks, Git Worktree is a tool that deserves a place in your development toolkit.&lt;/p&gt;

&lt;h3&gt;
  
  
  🤔 What Are Your Thoughts?
&lt;/h3&gt;

&lt;p&gt;Have you used Git Worktree before? What insights or tips do you have to share? Let’s spark a conversation in the comments below! Together, we can master this powerful feature and elevate our coding journeys. Happy coding! 💻✨&lt;/p&gt;

&lt;h3&gt;
  
  
  Special Thanks👏👏👏👏
&lt;/h3&gt;

&lt;p&gt;A huge thank you to the amazing developers and contributors in the Git community who brought us the Git Worktree feature! Your hard work and dedication have made it easier for developers like me to manage multiple branches seamlessly. &lt;br&gt;
Special mention to ThePrimeagen, whose engaging tutorials and insights on Git have helped countless developers enhance their skills. &lt;br&gt;
If you haven't checked out his content yet, you're missing out! His course on mastering Git is a must-watch for anyone looking to level up their version control game. &lt;br&gt;
Keep up the great work, everyone! Let's continue to learn and grow together in this incredible coding journey! 💻✨&lt;/p&gt;

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