Implementing Shopping Cart and Order Service with Kafka and Message Queues: A Comparative Analysis

How Kafka and Traditional Message Queues Handle Event-Driven Architectures

DotNet Full Stack Dev
4 min readDec 16, 2024

In modern applications, shopping cart and order services often communicate using event-driven architectures. Choosing between Apache Kafka and traditional Message Queues (e.g., RabbitMQ, Azure Service Bus) impacts performance, reliability, and scalability. This blog explores implementing a shopping cart and order service using both approaches, highlighting their differences, strengths, and ideal use cases.

Scenario Overview

We’ll create two services:

  1. Shopping Cart Service: Sends an event when a user places an order.
  2. Order Service: Consumes the event to process the order.

Kafka-Based Implementation

How Kafka Works

Kafka is a distributed, high-throughput log-based event streaming platform. Events are published to topics and consumed by multiple subscribers independently, ensuring scalability and fault tolerance.

📌Explore more at: https://dotnet-fullstack-dev.blogspot.com/
🌟 Clapping would be appreciated! 🚀

Implementation

1. Kafka Setup

  • Create a Kafka topic named order-events.

2. Shopping Cart Service (Producer)

using Confluent.Kafka;

public class ShoppingCartService
{
private readonly string _topic = "order-events";
private readonly ProducerConfig _config;

public ShoppingCartService()
{
_config = new ProducerConfig
{
BootstrapServers = "localhost:9092"
};
}

public async Task PlaceOrderAsync(string orderId, string userId)
{
using var producer = new ProducerBuilder<string, string>(_config).Build();
var orderEvent = $"{{\"OrderId\":\"{orderId}\",\"UserId\":\"{userId}\"}}";

await producer.ProduceAsync(_topic, new Message<string, string>
{
Key = orderId,
Value = orderEvent
});

Console.WriteLine($"Order placed: {orderEvent}");
}
}

3. Order Service (Consumer)

using Confluent.Kafka;

public class OrderService
{
private readonly string _topic = "order-events";
private readonly ConsumerConfig _config;

public OrderService()
{
_config = new ConsumerConfig
{
BootstrapServers = "localhost:9092",
GroupId = "order-service-group",
AutoOffsetReset = AutoOffsetReset.Earliest
};
}

public void StartProcessing()
{
using var consumer = new ConsumerBuilder<string, string>(_config).Build();
consumer.Subscribe(_topic);

Console.WriteLine("Order Service is processing orders...");

while (true)
{
var consumeResult = consumer.Consume();
Console.WriteLine($"Order received: {consumeResult.Message.Value}");
// Process the order
}
}
}

Strengths of Kafka

  1. Scalability: Kafka is built to handle high-throughput use cases and scales horizontally.
  2. Replayability: Events remain in the topic for a configurable period, allowing reprocessing.
  3. High Availability: Fault-tolerant architecture with replication across brokers.

Message Queue-Based Implementation

How Message Queues Work

Message queues like RabbitMQ or Azure Service Bus are point-to-point communication systems where producers send messages to a queue, and consumers pull messages to process them.

Implementation

1. RabbitMQ Setup

  • Create a queue named order-queue.

2. Shopping Cart Service (Producer)

using RabbitMQ.Client;
using System.Text;

public class ShoppingCartService
{
public void PlaceOrder(string orderId, string userId)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.QueueDeclare(queue: "order-queue", durable: false, exclusive: false, autoDelete: false, arguments: null);

var orderEvent = $"{{\"OrderId\":\"{orderId}\",\"UserId\":\"{userId}\"}}";
var body = Encoding.UTF8.GetBytes(orderEvent);

channel.BasicPublish(exchange: "", routingKey: "order-queue", basicProperties: null, body: body);

Console.WriteLine($"Order placed: {orderEvent}");
}
}

3. Order Service (Consumer)

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;

public class OrderService
{
public void StartProcessing()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.QueueDeclare(queue: "order-queue", durable: false, exclusive: false, autoDelete: false, arguments: null);

var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine($"Order received: {message}");
// Process the order
};

channel.BasicConsume(queue: "order-queue", autoAck: true, consumer: consumer);

Console.WriteLine("Order Service is processing orders...");
Console.ReadLine();
}
}

Strengths of Message Queues

  1. Simplicity: Easy to set up and understand for basic use cases.
  2. Direct Acknowledgments: Ensures message delivery and processing reliability.
  3. Flexibility: Supports various delivery guarantees (e.g., at-least-once, exactly-once).

Comparison: Kafka vs Message Queues

What Improves in Each Area?

Using Kafka

  • High Throughput: Best for applications with a large number of events (e.g., order processing in e-commerce).
  • Event Sourcing: Enables replaying events to reconstruct system state or handle errors.
  • Decoupling: Multiple services can independently consume the same event.

Using Message Queues

  • Ease of Use: Simplifies event-driven workflows for smaller-scale applications.
  • Guaranteed Delivery: Ensures reliable communication with acknowledgment mechanisms.
  • Resource Efficiency: Ideal for applications with limited message rates.

Conclusion

Both Kafka and Message Queues are powerful tools for enabling communication between services in event-driven architectures. The choice depends on your application’s scale, complexity, and requirements:

  • Choose Kafka for high-throughput, distributed, or replayable event streams.
  • Choose Message Queues for simpler, reliable, and point-to-point messaging.

Understanding the strengths and limitations of each helps you make the right decision for your architecture. Have you worked with Kafka or Message Queues? Share your experience in the comments below!

--

--

DotNet Full Stack Dev
DotNet Full Stack Dev

Written by DotNet Full Stack Dev

Join me to master .NET Full Stack Development & boost your skills by 1% daily with insights, examples, and techniques! https://dotnet-fullstack-dev.blogspot.com

No responses yet