Skip to content

Repository files navigation

🛒 Quickart — E-Commerce Microservices Backend

A production-grade, scalable e-commerce backend built with Spring Boot and Spring Cloud. Designed with a fully decoupled microservices architecture featuring event-driven communication, graph-based data storage, and gateway-level security.

Java Spring Boot Spring Cloud Neo4j Kafka License


📑 Table of Contents


📌 Project Overview

Quickart is a fully decoupled microservices-based e-commerce backend. Each service owns its own domain, can be deployed independently, and communicates with other services either synchronously via OpenFeign (when an immediate response is needed) or asynchronously via Apache Kafka (for fire-and-forget events).

Key design highlights:

  • JWT authentication is enforced at the API Gateway — no downstream service handles auth logic
  • Neo4j graph database is used to model complex entity relationships (users, products, orders)
  • Kafka decouples the order → payment → notification pipeline
  • Spring Cloud Config Server manages all configuration from a single Git-backed repository
  • A shared common library provides consistent exception handling and response wrappers across all services

💡 Why These Technology Choices?

Technology Reason
Neo4j (Graph DB) E-commerce data is inherently relational — products have categories, users have wishlists, orders link users to products. Neo4j models these as first-class graph relationships, making traversal queries faster and more natural than SQL joins.
Apache Kafka Order → Payment → Notification is an async pipeline. Using Kafka decouples these services so a slow email server won't delay order processing. It also provides durability — events are not lost if a consumer is temporarily down.
API Gateway + JWT Centralizing authentication at the gateway means downstream services are simpler, faster, and don't need to replicate security logic. The gateway validates the token and passes the user identity via a trusted header (X-User-Email).
Spring Cloud Config Managing configuration across 9 services manually is error-prone. A Git-backed config server means one place to change a value and all services pick it up on restart.
OpenFeign Declarative HTTP client — makes synchronous inter-service calls (e.g., checking product stock before placing an order) feel like local method calls, with built-in load balancing via Eureka.
Common Library Shared exception classes and response wrappers ensure consistent API responses across all services without duplicating code.

🏗️ System Architecture

                        ┌───────────────────┐
                        │   Config Server    │  ← Git-backed centralized config
                        │    Port: 8888      │
                        └────────┬──────────┘
                                 │ provides config on startup
                                 ▼
                        ┌───────────────────┐
                        │   Eureka Server    │  ← Service registry & discovery
                        │    Port: 8761      │
                        └────────┬──────────┘
                                 │ all services register here
                                 ▼
              ┌──────────────────────────────────────┐
              │          API Gateway                  │  ← Single entry point
              │           Port: 8080                  │    JWT validation
              │    Spring Cloud Gateway (WebFlux)     │    Route + CORS
              └───┬──────────┬──────────┬────────────┘
                  │          │          │
           ┌──────┘   ┌──────┘   ┌─────┘
           ▼          ▼          ▼
    User Service  Product Svc  Cart Service   ← Business Services
    Port: 8087    Port: 8086   Port: 8081       (Neo4j Graph DB)
                               │
                    Order Service   Payment Service
                    Port: 8083      Port: 8085
                          │              │
                          └──────┬───────┘
                                 │ Apache Kafka (Event Bus)
                                 ▼
                      Notification Service        ← Kafka Consumer
                         Port: 8082                 JavaMailSender
                                                     Gmail SMTP

🚀 Services

Service Port Responsibility
eureka-server 8761 Service registry — all services register and discover each other here
config-server 8888 Git-backed centralized configuration for all services
api-gateway 8080 Single entry point — JWT validation, request routing, CORS
user-service 8087 User registration, login, JWT generation, profile management
product-service 8086 Product catalog — create, update, search products
cart-service 8081 Shopping cart — add/remove items, checkout trigger
order-service 8083 Order creation and lifecycle management
payment-service 8085 Payment processing, invoice generation
notification-service 8082 Kafka consumer — sends transactional emails via Gmail SMTP
common library Shared module — custom exceptions, response wrappers, constants

🛠️ Tech Stack

Category Technology Version
Language Java 21
Framework Spring Boot 4.0.6
Microservices Spring Cloud 2025.1.1
Service Discovery Spring Cloud Netflix Eureka
Config Management Spring Cloud Config Server
API Gateway Spring Cloud Gateway (WebFlux)
Inter-service (Sync) OpenFeign
Inter-service (Async) Apache Kafka
Security Spring Security + JJWT 0.12.3
Database Neo4j Graph Database
Email JavaMailSender (Gmail SMTP)
API Docs SpringDoc OpenAPI / Swagger UI
Build Tool Maven 3.8+
Boilerplate Lombok

🔐 Security Design

Authentication is fully centralized at the API Gateway. No downstream service performs token validation — this keeps them lightweight and focused on business logic.

┌─────────────────────────────────────────────────────────┐
│                      JWT Flow                           │
│                                                         │
│  1. User logs in → User Service issues accessToken      │
│                    + refreshToken                       │
│                                                         │
│  2. Client sends: Authorization: Bearer <accessToken>   │
│                                                         │
│  3. API Gateway intercepts every request                │
│       ├── Validates JWT signature & expiry              │
│       ├── VALID   → strips token, adds X-User-Email     │
│       │             header, forwards to service         │
│       └── INVALID → returns 401 Unauthorized            │
│                                                         │
│  4. Downstream services trust X-User-Email header       │
│     (set by gateway, never by the client)               │
└─────────────────────────────────────────────────────────┘

Token lifecycle:

  • accessToken — expires in 2 hours
  • refreshToken — used to obtain a new access token via /api/user/refresh-token

Public routes (no JWT required): sign-up, verify, sign-in, forgot-password, reset-password, refresh-token


📡 Communication Strategy

Type Technology When Used Example
Synchronous OpenFeign Immediate response required Cart → Product (stock check before checkout)
Asynchronous Apache Kafka Fire-and-forget events Order → Notification (send confirmation email)
Discovery Eureka Resolve service host/port Any Feign call between services
Entry Point API Gateway All client requests Auth, routing, CORS handling

Design decision: Kafka is used for the order → payment → notification pipeline because these steps do not need to be synchronous. A customer placing an order should not wait for the email to send. Feign is used only where the calling service genuinely cannot proceed without a response (e.g., stock validation).


🔄 Event-Driven Flow

User places order
       │
       ▼
  Cart Service ──── Feign ────► Product Service
                               (validate stock availability)
       │
       │ Kafka: cart-checkout
       ▼
  Order Service (saves order, confirms)
       │
       ├──── Kafka: order-confirmed ────────────────────────┐
       │                                                    │
       │                                          Notification Service
       │                                          (order confirmation email)
       │
       └──── Kafka: order-confirmed ────► Payment Service
                                               │
                                               │ Kafka: payment-completed
                                               ▼
                                       Notification Service
                                       (payment receipt email)
                                               │
                                               │ Kafka: invoice-created
                                               ▼
                                       Notification Service
                                       (invoice email)

📦 Kafka Topics

Topic Producer Consumer(s) Purpose
cart-checkout cart-service order-service Trigger order creation after cart checkout
order-confirmed order-service payment-service, notification-service Notify payment + send order confirmation email
payment-completed payment-service notification-service Send payment receipt email
invoice-created payment-service notification-service Send invoice email to customer
stock-updated product-service cart-service Sync inventory changes to cart

⚙️ Centralized Configuration

All service configurations are stored in a dedicated Git repository, served by the Config Server at startup. No sensitive values are hardcoded in any service.

👉 Config repo: quickart-configs

quickart-configs/
├── application.properties            ← Shared by ALL services (Eureka URL, etc.)
├── api-gateway.yml
├── user-service.properties
├── product-service.properties
├── cart-service.properties
├── order-service.properties
├── payment-service.properties
└── notification-service.properties

Each service only needs two lines in its local bootstrap.properties:

spring.application.name=user-service
spring.config.import=configserver:http://localhost:8888

The Config Server then delivers the correct config file based on the service name.


⚡ Getting Started

Prerequisites

  • Java 21
  • Maven 3.8+
  • Neo4j (local install or AuraDB cloud)
  • Apache Kafka + Zookeeper running locally
  • Gmail account with an App Password enabled

1. Clone the Repository

git clone https://github.com/SKgain/quickart-backend.git
cd quickart-backend

2. Install the Common Library

The common module is a shared library used by all services. Install it to your local Maven repository first:

cd common
mvn clean install
cd ..

3. Configure Environment Variables

Update the following in the quickart-configs repo or set as environment variables:

# Neo4j
spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=your_password

# Apache Kafka
spring.kafka.bootstrap-servers=localhost:9092

# Gmail SMTP (Notification Service)
spring.mail.username=your@gmail.com
spring.mail.password=your_app_password

# JWT Secret (User Service & API Gateway)
jwt.secret=your_base64_encoded_secret_key
jwt.access-token-expiry=7200000

4. Start Services in Order

⚠️ Order matters. Services depend on each other at startup.

# Step 1 — Eureka Server (must be first)
cd eureka-server
mvn spring-boot:run

# Step 2 — Config Server (must be second)
cd ../config-server
mvn spring-boot:run

# Step 3 — API Gateway
cd ../api-gateway
mvn spring-boot:run

# Step 4 — Business Services (any order)
cd ../user-service && mvn spring-boot:run
cd ../product-service && mvn spring-boot:run
cd ../cart-service && mvn spring-boot:run
cd ../order-service && mvn spring-boot:run
cd ../payment-service && mvn spring-boot:run
cd ../notification-service && mvn spring-boot:run

5. Verify Setup

Dashboard URL
Eureka Dashboard http://localhost:8761
API Gateway http://localhost:8080
Swagger UI (all services) http://localhost:8080/swagger-ui.html

📡 API Endpoints

All requests go through the API Gateway at port 8080. Do not call services directly.

🔐 User Service — Authentication

Method Endpoint Description Auth
POST /api/user/sign-up Register a new user Public
GET /api/user/verify Verify email with token Public
POST /api/user/sign-in Login, receive access + refresh tokens Public
POST /api/user/resend-verification Resend email verification Public
POST /api/user/forgot-password Send password reset email Public
POST /api/user/reset-password Reset password using token Public
POST /api/user/refresh-token Exchange refresh token for new access token Public
POST /api/user/logout Invalidate user session 🔒 Private
GET /api/user/profile Get authenticated user's profile 🔒 Private

🔑 Authentication Flow

Step 1 → POST /api/user/sign-up
              ↓
          Verification email sent to user's inbox

Step 2 → GET /api/user/verify?token=xxx&email=xxx
              ↓
          Account activated

Step 3 → POST /api/user/sign-in
              ↓
          Response: { accessToken, refreshToken }

Step 4 → All subsequent requests:
          Header: Authorization: Bearer <accessToken>
              ↓
          API Gateway validates → adds X-User-Email header → forwards request

Step 5 → Access token expires (2 hours):
          POST /api/user/refresh-token
              ↓
          Response: { new accessToken, new refreshToken }

📁 Project Structure

quickart-backend/
│
├── common/                              ← Shared library (install first)
│   └── src/main/java/com/skgain/common/
│       ├── exceptions/                  # Custom exceptions + GlobalExceptionHandler
│       ├── responses/                   # ApiResponse wrapper, EmailResponse
│       └── constants/                   # ErrorCode enum, SecurityConstant
│
├── eureka-server/                       ← Service registry
│   └── src/main/resources/
│       └── application.properties
│
├── config-server/                       ← Centralized config server
│   └── src/main/resources/
│       └── application.properties       # Points to quickart-configs Git repo
│
├── api-gateway/                         ← Gateway — JWT filter, routing, CORS
│   └── src/main/java/com/skgain/api_gateway/
│       ├── auth/                        # JwtAuthFilter, JwtService, SecurityConfig
│       └── configs/                     # Route definitions, GatewayConfig
│
├── user-service/                        ← Auth + user domain (Neo4j)
│   └── src/main/java/com/skgain/user_service/
│       ├── auth/                        # JWT generation, SecurityConfig
│       ├── node/                        # Neo4j node entities (User, Token, etc.)
│       ├── repositories/                # Neo4j repositories
│       ├── services/                    # Business logic
│       ├── feigns/                      # Feign clients to other services
│       └── controllers/                 # REST controllers
│
├── product-service/                     ← Product catalog domain (Neo4j)
├── cart-service/                        ← Cart domain (Neo4j)
├── order-service/                       ← Order domain (Neo4j)
├── payment-service/                     ← Payment domain (Neo4j)
│
└── notification-service/                ← Email domain (Kafka consumer)
    └── src/main/resources/
        └── templates/                   # HTML email templates
            ├── signup-verification-email.html
            └── reset-password-email.html

📚 API Documentation

All services are aggregated under the API Gateway's Swagger UI. No need to access individual service Swagger pages.

URL Description
http://localhost:8080/swagger-ui.html Unified Swagger UI for all services

Use the service dropdown in Swagger UI to switch between:

  • User Service
  • Product Service
  • Cart Service
  • Order Service
  • Payment Service
  • Notification Service

📧 Email Notifications

Email Kafka Trigger Description
Signup verification — (direct) Sent on registration, contains verification link
Password reset — (direct) Contains secure reset link
Order confirmation order-confirmed Sent to customer after order is placed
Payment receipt payment-completed Sent after successful payment
Invoice invoice-created Invoice PDF/details sent to customer

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature-name
  3. Commit with a meaningful message: git commit -m "feat: describe your change"
  4. Push and open a Pull Request

📄 License

This project is licensed under the MIT License.


Built with ☕ Java + Spring Boot  |  SKgain

About

A production-grade e-commerce backend built with Spring Boot microservices. Features JWT auth at the API Gateway, Neo4j, Apache Kafka, Spring Cloud Config Server, Eureka service discovery, OpenFeign, and automated email notifications.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages