← Back to list

🏰 Taming the Data Chaos: Your First Adventure with Kafka & Node.js

Imagine you’ve just launched a new online store. Orders are trickling in, and everything is running smoothly. Your “Order Service” gets an…

Prabhat Ranjan Singh · 2025-10-04 04:32 · 0 claps · 6.4 min read
#kafka #kafka-connect #docker-compose #docker-image #nodejs
Open on Medium ↗
Wiki topics: 🌐 · Web Development ☁️ · DevOps & Cloud 🏃 · Running & Endurance

🏰 Taming the Data Chaos: Your First Adventure with Kafka & Node.js

Imagine you’ve just launched a new online store. Orders are trickling in, and everything is running smoothly. Your “Order Service” gets an order and tells the “Processing Service” what to do. Simple!

But then, a flash sale goes viral. 🚀 Suddenly, thousands of orders flood in every minute. Your Processing Service, like a frantic chef with too many tickets, gets overwhelmed and crashes. The Order Service tries to send more orders, but there’s nowhere for them to go. New orders fail, customers are angry, and your dream launch becomes a nightmare.

This is the chaos of a tightly-coupled system. When one part fails or slows down, the whole system grinds to a halt.

What if you had a magical, infinitely long conveyor belt between your services? The Order Service could place orders on the belt as fast as it wants, and the Processing Service could pick them off at its own pace. Even if the processor stops for a while, the orders just queue up safely on the belt, waiting to be handled.

That magical conveyor belt is Apache Kafka. It’s not just a message queue; it’s a distributed streaming platform that acts as the central nervous system for modern applications. Today, we’ll build that exact system.

🤔 “But Wait, What About WebSockets or SSE?”

That’s a great question! Tools like WebSockets and Server-Sent Events (SSE) are fantastic for real-time communication between a user’s browser and a server — think of a live chat app or a stock ticker. It’s like a telephone call; the connection is direct and immediate.

Kafka solves a different problem. It’s for communication between your back-end services. It’s less like a phone call and more like a highly reliable, organized post office.

  • A service (Producer) drops off a letter (a message or event) at the post office.
  • It doesn’t care who picks it up or when. Its job is done.
  • Other services (Consumers) can subscribe to specific mailboxes (Topics) and pick up letters whenever they’re ready.

This “post office” model is what prevents the chaos we described earlier.

💥 The Problem We’re Solving: The Domino Effect

Without Kafka, your system is a line of dominoes.

  • What if the consumer is down? 😨 The producer can’t send data. The order is lost. Domino falls.
  • What if the consumer is slow? 🐌 The producer has to wait, slowing down the entire system. Domino wobbles.
  • What if you get a huge spike in orders? 🌊 The consumer gets overwhelmed and crashes. All dominoes fall.
  • What if you want to add another service (like an email notification service)? 🤔 You have to change the producer’s code to tell it about this new service, making your system more brittle.

✨ The Kafka Solution: A Resilient, Decoupled System

By placing Kafka in the middle, you break these direct dependencies.

  • Resilience 🛡️: If the consumer crashes, the producer keeps sending orders to Kafka. The messages wait safely in the orders topic until the consumer is back online. No data is lost.
  • Speed 💨: The producer sends a message and immediately moves on. It doesn’t wait for the consumer, making your application incredibly fast and responsive.
  • Buffering 🌊: That sudden spike of 10,000 orders? Kafka holds them all, acting as a buffer. The consumer can process them at its own pace without being overwhelmed.
  • Scalability ✨: Is one consumer too slow? Just launch five more! Kafka automatically distributes the work among them, processing orders five times faster without any code changes in the producer.

Now, let’s stop talking and start building!

🛠️ The Blueprint: Our E-Commerce Order System

We’ll build a simple system with two main parts:

  • Producer: A Node.js script that creates fake e-commerce order data every second and sends it to a Kafka topic called orders.
  • Consumer: Another Node.js script that listens to the orders topic, receives the data, and prints it to the console.

Folder Structure

First, create a main folder called kafka-order-system. Inside, your structure will look like this:

kafka-order-system/
├── src/
│   ├── producer.js
│   └── consumer.js
├── docker-compose.yml
├── package.json
└── package-lock.json

🚀 Let’s Build! A Step-by-Step Guide

Step 1: 🐳 Laying the Foundation with Docker

We need Kafka to run, but installing it manually can be tricky. Instead, we’ll use Docker to spin up Kafka, its dependency Zookeeper, and a handy UI called Kafdrop with one command.

Create the docker-compose.yml file in your project's root and add this:

version: '3.8'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:7.3.2
    hostname: zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
  kafka:
    image: confluentinc/cp-kafka:7.3.2
    hostname: kafka
    container_name: kafka
    depends_on:
      - zookeeper
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181'
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
  kafdrop:
    image: obsidiandynamics/kafdrop:latest
    container_name: kafdrop
    depends_on:
      - kafka
    ports:
      - "9000:9000"
    environment:
      KAFKA_BROKERCONNECT: "kafka:29092"

Step 2: 📦 Setting Up Our Node.js Workshop

Now, let’s get our Node.js environment ready. Open your terminal in the kafka-order-system directory.

  • Initialize npm:
  • npm init -y
  • Install Dependencies: We need kafkajs to talk to Kafka and @faker-js/faker to generate our dummy data.
  • npm install kafkajs @faker-js/faker
  • Use ES Modules: To use the modern import syntax, add this line to your package.json file:
  • "type": "module",

Step 3: ✍️ Writing the Application Code

Create the src folder and the two JavaScript files inside it.

The Producer (src/producer.js)

This script is our “Order Service.” It will create a fake order every second and drop it into the orders topic in Kafka.

import { Kafka } from 'kafkajs';
import { faker } from '@faker-js/faker';
// 1. Create a Kafka client
const kafka = new Kafka({
  clientId: 'my-producer',
  brokers: ['localhost:9092'], // Kafka broker address
});
const producer = kafka.producer();
const topic = 'orders';
const runProducer = async () => {
  try {
    // 2. Connect the producer
    await producer.connect();
    console.log("✅ Producer connected successfully.");
    // 3. Send a new message every second
    setInterval(async () => {
      const orderMessage = {
        orderId: faker.string.uuid(),
        product: faker.commerce.productName(),
        quantity: faker.number.int({ min: 1, max: 5 }),
        price: parseFloat(faker.commerce.price()),
        customer: {
          name: faker.person.fullName(),
          email: faker.internet.email(),
        },
        timestamp: new Date().toISOString(),
      };
      await producer.send({
        topic: topic,
        messages: [{ value: JSON.stringify(orderMessage) }],
      });
      console.log(`📦 Sent order: ${orderMessage.orderId}`);
    }, 1000); // Send a message every 1000ms (1 second)
  } catch (error) {
    console.error("❌ Error connecting or sending message:", error);
  }
};
runProducer();

The Consumer (src/consumer.js)

This script is our “Processing Service.” It connects to Kafka, subscribes to the orders topic, and logs every message it receives.

import { Kafka } from 'kafkajs';
// 1. Create a Kafka client
const kafka = new Kafka({
  clientId: 'my-consumer',
  brokers: ['localhost:9092'],
});
const consumer = kafka.consumer({ groupId: 'order-processing-group' });
const topic = 'orders';
const runConsumer = async () => {
  try {
    // 2. Connect the consumer
    await consumer.connect();
    console.log("✅ Consumer connected successfully.");
    // 3. Subscribe to the topic
    await consumer.subscribe({ topic: topic, fromBeginning: true });
    // 4. Run the consumer to listen for messages
    await consumer.run({
      eachMessage: async ({ topic, partition, message }) => {
        const order = JSON.parse(message.value.toString());
        console.log(`📥 Received new order!
          Topic: ${topic}
          Partition: ${partition}
          Order ID: ${order.orderId}
          Product: ${order.product}
        `);
      },
    });
  } catch (error) {
    console.error("❌ Error connecting or running consumer:", error);
  }
};
runConsumer();

Step 4: 🎉 The Grand Finale: Run Everything!

It’s time to see the magic happen. You’ll need two separate terminal windows.

  • Start Kafka: In your first terminal, at the root of your project, start the Docker containers.
  • docker-compose up -d
  • This might take a minute the first time.
  • Start the Consumer: In the same terminal, start the consumer. It will connect and wait patiently for orders.
  • node src/consumer.js
  • You should see: ✅ Consumer connected successfully.
  • Start the Producer: Now, open a second terminal window. Start the producer to begin generating data.
  • node src/producer.js
  • You should see: ✅ Producer connected successfully. followed by 📦 Sent order: ... every second.

Expected Outcome: Your consumer terminal will immediately spring to life, printing 📥 Received new order! logs as messages arrive from the producer, relayed perfectly through Kafka.

See it for Yourself with Kafdrop UI

Open your browser and go to http://localhost:9000. This is the Kafdrop UI. You can click on the orders topic to see the messages flowing in real-time. It's a fantastic way to confirm that your data is moving through the system visually.

To Stop Everything

  • Stop the producer and consumer scripts in their terminals by pressing Ctrl + C.
  • Stop the Kafka environment with this command:
  • docker-compose down

💡 Enhanced Tips for Your Kafka Journey

Congratulations! You’ve just built your first event-driven system. Here are a few tips as you explore further:

  • Consumer Groups are Key: The groupId: 'order-processing-group' In our consumer, it is powerful. If you start another consumer with the same group ID, Kafka will automatically balance the orders between them, giving you instant scalability.
  • Think About Data Schema: In a real-world app, you’d want to enforce a structure for your messages. Tools like Avro help ensure that producers and consumers always agree on the data format.
  • Handle Errors Gracefully: What if your consumer fails to process a message? Kafka has built-in retry mechanisms and concepts like “Dead Letter Queues” to handle failures without losing data.
  • Explore Partitions: A Kafka topic is divided into partitions. This is how it achieves massive parallelism. Messages with the same key (e.g., a customer ID) can be sent to the same partition to guarantee order of processing for that specific customer.

🙏 Thank You!

Thank you for following along on this adventure! You’ve taken a massive step from traditional, brittle software design to building a modern, resilient, and scalable system. The principles you’ve learned here are the bedrock of the applications that power our digital world.

Happy coding!


메타데이터
post_id
b51884820e33
slug
taming-the-data-chaos-your-first-adventure-with-kafka-node-js-b51884820e33
url
https://medium.com/@topi9864/taming-the-data-chaos-your-first-adventure-with-kafka-node-js-b51884820e33
canonical_url
https://medium.com/@topi9864/taming-the-data-chaos-your-first-adventure-with-kafka-node-js-b51884820e33
author_url
https://medium.com/@topi9864
status
ok
fetched_at
2026-07-17 01:49:50