Inside Levomart: A Full-Stack Polyglot Microservices Architecture for E-commerce

Rajan bansalRajan bansal
13 min read

Building Levomart: My Journey Creating a Scalable E-commerce Platform Using Microservices & Kubernetes

⚑ TL;DR

  • βœ… Built Levomart β€” a scalable, polyglot microservices e-commerce backend

  • πŸ› οΈ Tech stack: Java Spring Boot, Node.js/Express, Kafka, Docker, Kubernetes, PostgreSQL, MongoDB

  • πŸ” Features: JWT Auth, Product, Cart, Order, Payment services with REST + Kafka events

  • 🧱 Shared JSON-schema messaging, Swagger/OpenAPI docs, monorepo + Git pre-push safety hook

  • πŸš€ CI/CD via GitHub Actions & Skaffold; deployed locally


Introduction

Welcome to my technical blog series! πŸ‘‹

Over the past few months, I’ve been building Levomart, a full-stack e-commerce platform designed with microservices architecture, event-driven communication, and cloud-native deployment using Docker, Kubernetes, and Kafka.

The goal?
To gain real-world engineering experience by designing and deploying a scalable, production-grade system β€” the kind that mirrors what backend engineers at top product-based and big tech companies work on every day.

This blog isn't just about showing a finished project. It's about documenting the why, what, and how β€” the entire journey of building a system from scratch:

πŸš€ Whether you're an aspiring backend developer, a student preparing for SDE interviews, or someone curious about scalable systems β€” this blog aims to be informative, technical, and genuinely helpful.

Let’s dive in! πŸ”§πŸ“¦β˜οΈ


Problem Statement / Goal

As a developer preparing for software engineering roles at top tech companies, I wanted to go beyond just practicing DSA and building small apps. I needed to work on something that would simulate the kind of challenges backend engineers face in real-world systems.

That’s how this project was decided β€” a personal project to design, build, and deploy a full-stack, production-ready e-commerce platform using modern technologies and architectural patterns.

After completing a backend systems course on Udemy (https://www.udemy.com/course/microservices-with-node-js-and-react), I realized the best way to truly understand these concepts was to build something from the ground up and apply them in a real project.

Key Goals Behind This Project:

  • βœ… Build a microservices-based architecture from scratch

  • βœ… Implement secure user authentication with role-based access

  • βœ… Set up Kafka-based event-driven communication between services

  • βœ… Use Docker for containerization and Kubernetes for orchestration

  • βœ… Deploy everything on AWS EC2, simulating cloud production

  • βœ… Learn and implement CI/CD pipelines, automated testing, and code coverage tools

  • βœ… Document the entire journey to help others learn from it

This project was more than just about writing code β€” it was about designing a realistic system that’s scalable, testable, and production-ready. It gave me the opportunity to explore different tools, solve practical engineering problems, and better understand the infrastructure behind real applications.


Architecture Overview

Before diving into individual services and technical details, here's a high-level overview of how the system is structured.

Levomart follows a Polygot microservices architecture, with each service handling a specific business domain. The services communicate using both REST APIs and asynchronous event-driven messaging via Kafka.

🧠 High-Level Tech Stack:

LayerTechnology
Backend ServicesJava Spring Boot (Auth, Payment, Cart), Node.js/Express (Product, Order )
CommunicationREST APIs, Kafka (for async events)
DatabasesPostgreSQL, Redis, MongoDB
ContainerizationDocker
OrchestrationKubernetes
Dev ToolsSkaffold, Postman, GitHub Actions, warp, vs-code
CI/CDGitHub Actions

You can view the full Mono Repo structure and services in the GitHub repository.

https://github.com/Rajan235/LevoMart

πŸ“‚ Folder Structure

levomart/
β”œβ”€β”€ auth/               # Spring Boot Auth Service
β”œβ”€β”€ cart/               # Redis-backed Cart Service
β”œβ”€β”€ product/            # Product CRUD Service (Node.js)
β”œβ”€β”€ order/              # Kafka Order Service (Node.js)
β”œβ”€β”€ payment/            # Stripe Integration (Spring Boot)
β”œβ”€β”€ client/             # Next.js frontend
β”œβ”€β”€ shared-schemas/     # Shared Kafka DTOs (JSON Schema)
β”œβ”€β”€ k8s/                # Kubernetes manifests
β”œβ”€β”€ cloudbuild.yaml     # Google Cloud Build
└── skaffold.yaml       # Skaffold Dev Config

πŸ§‘β€πŸ’» Quick Start (Local)

# 1. Install Docker Desktop and enable Kubernetes

# 2. Install kubectl and Skaffold
brew install kubectl
brew install skaffold

# 3. Apply Ingress-NGINX Controller (for routing)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml

# 4. Map hostname in /etc/hosts
sudo nano /etc/hosts

# Add this line to map levomart.local to localhost
127.0.0.1    levomart.local

# 5. Start local development with Skaffold
skaffold dev

πŸ’‘ Skaffold will continuously build, watch, and redeploy your services in your local Kubernetes cluster. This can be resource-heavy β€” close other background apps if needed.

πŸ“– API Documentation & Sample Usage

  • All microservices expose REST APIs.

  • Swagger UI is integrated and available for each service (e.g., http://levomart.local/api/auth/swagger-ui.html) for interactive API exploration and testing.

# Example: Get all products
GET /api/products

curl http://levomart.local/api/products

System Architecture Diagram

A typical request flow:

  1. A user (USER, SELLER, ADMIN) accesses the app via the frontend (or REST client like Postman).

  2. Requests are routed via the Nginx Ingress Controller to the correct service.

  3. Services interact via REST or publish events to Kafka.

  4. Each service has its own database (PostgreSQL, MongoDB or Redis) following the database-per-service pattern.

  5. Kafka is used for decoupled communication β€” e.g., product creation, order placed, stock updates.

  6. CI/CD pipelines handle testing, image builds, and deployments.


☸️ Kubernetes Cluster Layout

This is cluster diagram containing all the things inside cluster

  • All services along with their Databases are Dockerized

  • NGINX Ingress Controller handles routing (levomart.local)

  • Skaffold simplifies iterative development with auto-rebuilds & re-deploys

  • Kubernetes manifests include Deployments, Services, Secrets, ConfigMaps, and Ingress where each service has its own config map and secrets (defined in YAML) in k8s for environment variables

  • Added Kubernetes Jobs as well to run script at start of each container for specific services

  • Kafka + zookeeper is also inside this cluster as well

🧠 Monorepo & Development Strategy

All services exist in a shared monorepo, simplifying:

  • Shared JSON schemas for Kafka events

  • Unified CI/CD workflows

  • Local development with Skaffold & Docker Compose

I also use a Git pre-push hook to run tests and builds automatically before pushing β€” ensuring only green code is pushed.


πŸ“© Kafka Event-Driven Design

Services emit and consume events such as:

  • Apache Kafka powers asynchronous communication across services

  • Topics follow a clean namespace convention (e.g., product:created, order:created)

  • we define both consumers and producers based on need and define k8s job to create topic on start of Kafka

  • Enables decoupling between services while maintaining eventual consistency

  • Consumers handle retries, idempotency, and clean shutdown with SIGINT/SIGTERM

  • Kafka helps scale horizontally without tight service coupling

Each event is validated against shared JSON schemas. This ensures contract consistency across languages and services.


βš™οΈ CI/CD Architecture

This was planned CI/CD pipeline although as personal project code is written only not used highly

Using GitHub Actions, where each service pipeline includes:

Implemented 4 branch methodology where code goes from

feature branch β†’ dev branch β†’ test/staging branch β†’ main/master/production branch

  1. Linting & Unit/Integration tests

  2. Code coverage (Jacoco for Spring, Jest for Node.js)

  3. Docker build & push

  4. Each service has its own CI/CD pipeline with GitHub Actions:

  5. Runs automatically on PRs, merges, and main branch updates

  6. implement conditional workflows


πŸ“œ Swagger / OpenAPI Documentation

All REST endpoints are documented via Swagger JSDoc or annotations. This allows:

  • Automatic API docs generation

  • Interactive Explorer for front-end devs or clients


πŸ§‘β€πŸ’» UI Preview

I built a simple Next.js frontend to interact with Levomart services:

I used Nextjs because it offers server side rendering and client side rendering easily

  • In client we have our Backend For Frontend (BFF) which make direct rest request to services in cluster for server side rendering and custom routes

  • ShadCN and tailwind is used for UI


Key Technical Decisions

In this section, I’ll break down the major components of Levomart and the rationale behind the tools and architecture choices.


πŸ” Authentication Service (Spring Boot + PostgreSQL)

  • Built with Java Spring Boot and Spring Security

  • Implements JWT-based authentication with access token and role-based control

  • Supports roles: USER, SELLER, ADMIN

  • Tested using JUnit, Mockito, and H2 for integration tests


πŸ›’ Cart Service (Spring Boot + Redis)

  • Uses Redis as the primary data store to support fast, in-memory cart operations

  • Kafka used to sync cart updates when products or orders change


🧾 Product Service (Node.js + Express + MongoDB)

  • Developed using Node.js, Express, TypeScript and MongoDB

  • Stores product data in MongoDB, ideal for flexible product schema (categories, variations, etc.)

  • Routes separated for sellers and admins and users

  • Emits product:created and product:updated events to Kafka


πŸ“¦ Order Service (Node.js + Express + PostgreSQL)

  • Uses PostgreSQL for reliable relational order data (user, product, price, timestamp)

  • Has its own minimal product table to avoid requesting product service for details

  • Subscribes to Kafka events like product created, payment succeeded to update its product table and change order status

  • Managed using Prisma ORM for type-safe queries and migrations


πŸ’³ Payment Service (Spring Boot + PostgreSQL)

  • Simulates payment confirmation (Integration with Stripe)

  • Future-proofed for multi-gateway support (webhooks, retries, etc.)


Challenges & Learnings

Along the way, I encountered many real-world engineering challenges that taught me valuable lessons in architecture, tooling, infrastructure, and development workflows.

Here are some of the major challenges and what I learned from each:


πŸ” Kafka Configuration & Event Structure Consistency

  • Setting up Apache Kafka for reliable event-based communication was a big learning curve.

  • Ensuring consistent message formats across polyglot microservices (Java + Node.js) was critical to avoid runtime issues.

  • Solution:

    • Defined strict JSON schemas for all events (e.g., product:created, order:created)

    • Used shared schema definitions across services for type-safe Kafka event handling


🌐 Polyglot Microservices & Data Consistency

  • Managing data contracts and response/request consistency between Spring Boot and Node.js services was tricky.

  • Solved this by:

    • Using DTOs (Data Transfer Objects) in both backends

    • Creating clearly defined interfaces and schemas for internal APIs

    • Validating inputs using frameworks like class-validator in Node.js and Bean Validation in Spring Boot


☸️ Kubernetes YAMLs: Ingress, ConfigMaps & Deployments

  • Writing Kubernetes manifests for Deployments, Services, ConfigMaps, Secrets, and Ingress was a challenge at first.

  • Minor mistakes (like wrong path rewrite or missing env key) could silently break routing or crash pods.

  • Learned to:

    • Validate YAML using kubectl explain and VS Code plugins

    • Use Skaffold profiles to manage multiple environments (local/dev)

    • Create reusable Helm-style configurations (planned next)


πŸ” Managing Environment Variables

  • Passing environment variables securely and correctly between Docker, Kubernetes, and CI pipelines was more complex than expected.

  • Mistakes like missing DB URLs or incorrect Kafka host strings led to silent failures.

  • Resolved by:

    • Using K8s Secrets and ConfigMaps to manage environment data

    • Documenting .env file structure and syncing dev/prod configurations

    • Testing startup environments using Skaffold and local Docker Compose setups


πŸ§ͺ Writing Tests: Unit, Integration, and Mocks

  • Writing unit and integration tests across services with different stacks (Spring Boot and Node.js) was a major challenge.

  • Specifically, mocking services like Redis, Kafka, and DBs added complexity.

  • Key learnings:

    • Use H2 and Testcontainers for Spring Boot integration tests

    • Mock external modules using Jest, supertest, and nock in Node.js

    • Set up dev, test, and prod environments using .env + K8s profiles


🧠 Final Takeaways

  • System design goes beyond writing API endpoints β€” it’s about building a reliable, testable, observable, and maintainable architecture

  • Tools like Kafka, K8s, and CI/CD pipelines have steep learning curves β€” but they add tremendous power and flexibility

  • The biggest wins often came from solving infrastructure and consistency issues, not just writing new features


These challenges helped me grow as a developer β€” not just in coding, but in system thinking, debugging, environment management, and automation. They made this project feel more like working on a real production-grade system than just a side project.


βœ… What’s Working Today

  • πŸ” Secure JWT-based authentication with role management (USER, SELLER, ADMIN)

  • πŸ›’ Fully functional microservices: Auth, Product, Cart, Order, and Payment β€” each independently deployable

  • ☁️ All services are Dockerized and deployed on a local Kubernetes cluster

  • 🌐 NGINX Ingress routing configured for domain-level access via levomart.local

  • πŸ—ƒοΈ Polyglot backend stack:

    • Java Spring Boot + PostgreSQL (Auth, Cart, Payment)

    • Node.js/Express + MongoDB/PostgreSQL (Product, Order)

  • πŸ“© Kafka event-driven architecture implemented with consistent JSON schemas across services

  • πŸ§ͺ Unit & integration testing with test environments configured for each service

  • πŸš€ CI/CD pipelines using GitHub Actions for test automation, code coverage, and optional deployment

  • πŸ” Skaffold for local development workflows, with support for hot reload and multi-service sync


It became much more than just a side project β€” it became a personal case study in learning how real systems work, and building one from the ground up.


Next Steps and Future Enhancements

While It is already a solid foundation for a scalable, modular e-commerce backend, my goal is to evolve it into a complete, real-world, production-grade platform. The next phase includes improvements across infrastructure, features, performance, and usability.


🧠 Architectural & Protocol Enhancements

  • πŸ”„ Build a GraphQL-based BFF (Backend for Frontend) for unified API consumption

  • 🧬 Use gRPC protocol for internal service-to-service communication to reduce latency and enforce strict contracts

  • ☁️ Migrate Kubernetes setup to AWS EKS for better scalability and managed infrastructure

  • πŸ“¦ Adopt Helm for templated deployments and cert-manager for TLS/SSL automation

  • πŸ” Manage secrets with AWS Secrets Manager or Sealed Secrets in K8s

  • πŸ“œ Use shared Avro (binary format) instead of Json for Kafka event validation and performance


πŸ’Ό Business & Feature Expansion

  • πŸ‘€ User Module Enhancements: Profile settings, saved addresses, preferences

  • 🧾 Seller Features: Inventory tracking, bulk product uploads, alerts

  • ⭐ Review & Rating System for products and sellers

  • 🚚 Delivery & Logistics Module: Order status, ETA, shipment integration

  • πŸ“Š Analytics Dashboards: Sales graphs, order volume trends, conversion rates for sellers/admins


🧠 Intelligent & User-Focused Additions

  • πŸ€– Add a Chatbot Service (rule-based or GPT-powered) to assist customers with FAQs, orders, and support

  • πŸ’¬ Integrate chatbot via REST/gRPC with intent recognition and fallback support


πŸ“± Frontend & Mobile Plans

  • Build a React Native or Flutter mobile app connected via BFF layer

πŸ“Š Performance & Observability

  • πŸ“ˆ Add observability stack: Prometheus, Grafana, and Loki for logs

  • Track:

    • Kafka consumer lag

    • Database query performance

    • Memory/CPU metrics and alerts

  • πŸ” Improve Caching:

    • Optimize Redis usage for cart, sessions, product listing

    • Use cache invalidation strategies for high-traffic endpoints


πŸ§ͺ Testing & CI/CD Improvements

  • Expand unit and integration testing using Test containers, mock servers, and schema contracts

  • Enhance and Use CI/CD pipeline extensively with storage of artifacts and tagging of versions


Final Thoughts

Building this project has been one of the most challenging, fulfilling, and educational projects I’ve worked on so far. It allowed me to simulate a real-world software engineering environment β€” from designing scalable systems and handling service communication to writing tests, setting up CI/CD pipelines, and deploying on the cloud.

What started as a learning experiment became a full-fledged backend platform that reflects my interest in backend architecture, distributed systems, DevOps, and production-level practices.

This project taught me that:

  • Writing code is just one part of the equation and design principles are very important instead of just feature working

  • writing code is not that tough what makes hard is writing good and scalable code

  • Designing resilient, maintainable systems is what truly makes a backend engineer stand out

  • Solving real engineering challenges is the best way to learn and grow


πŸ™Œ Thanks for Reading

If you found this blog helpful or insightful, feel free to share it or reach out. I’d love to:

  • Hear your thoughts

  • Collaborate on similar projects

  • Or chat about backend, system design, and anything in between!


πŸ“¬ Let’s Connect


Thanks again for joining me on this journey β€” more updates coming soon! πŸš€

0
Subscribe to my newsletter

Read articles from Rajan bansal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rajan bansal
Rajan bansal