Skip to content

aszender/enterprise-microservices-platform

Repository files navigation

πŸš€ Enterprise Microservices Platform

Full-Stack Demo: Java 17 + Spring Boot 3 + gRPC + Kafka + Redis + PostgreSQL + Vue 3 + React 18

A production-ready microservices architecture demonstrating enterprise patterns for distributed systems, event-driven communication, and modern frontend development.

Java Spring Boot Vue React Kafka Redis PostgreSQL gRPC


πŸ“‹ Table of Contents


πŸ— Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              FRONTEND LAYER                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
β”‚  β”‚     Vue 3 + Vite    β”‚              β”‚   React 18 + Vite   β”‚               β”‚
β”‚  β”‚   (Port 5173)       β”‚              β”‚   (Port 5174)       β”‚               β”‚
β”‚  β”‚  β€’ Composition API  β”‚              β”‚  β€’ Redux Toolkit    β”‚               β”‚
β”‚  β”‚  β€’ Reactive Store   β”‚              β”‚  β€’ Custom Hooks     β”‚               β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β”‚             β”‚                                    β”‚                          β”‚
β”‚             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β”‚
β”‚                            β”‚ REST/HTTP                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            β–Ό          API GATEWAY / PROXY                   β”‚
β”‚                     Vite Dev Proxy (routes /api/* to services)              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      BACKEND SERVICES                                        β”‚
β”‚                            β”‚                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
β”‚  β”‚                         β–Ό                                  β”‚              β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚              β”‚
β”‚  β”‚  β”‚   PRODUCTS   β”‚  β”‚    ORDERS    β”‚  β”‚  INVENTORY   β”‚     β”‚              β”‚
β”‚  β”‚  β”‚   SERVICE    β”‚  β”‚   SERVICE    β”‚  β”‚   SERVICE    β”‚     β”‚              β”‚
β”‚  β”‚  β”‚  (Port 8080) β”‚  β”‚  (Port 8081) β”‚  β”‚  (Port 8082) β”‚     β”‚              β”‚
β”‚  β”‚  β”‚              β”‚  β”‚              β”‚  β”‚              β”‚     β”‚              β”‚
β”‚  β”‚  β”‚ β€’ REST API   β”‚  β”‚ β€’ REST API   β”‚  β”‚ β€’ REST API   β”‚     β”‚              β”‚
β”‚  β”‚  β”‚ β€’ JWT Auth   β”‚  β”‚ β€’ JWT Auth   β”‚  β”‚ β€’ gRPC Serverβ”‚     β”‚              β”‚
β”‚  β”‚  β”‚ β€’ Redis Cacheβ”‚  β”‚ β€’ gRPC Clientβ”‚  β”‚   (Port 9090)β”‚     β”‚              β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚              β”‚
β”‚  β”‚         β”‚                 β”‚                  β”‚             β”‚              β”‚
β”‚  β”‚         β”‚                 β”‚    gRPC (sync)   β”‚             β”‚              β”‚
β”‚  β”‚         β”‚                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚              β”‚
β”‚  β”‚         β”‚                                                  β”‚              β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚
β”‚            β”‚                                                                 β”‚
β”‚            β”‚  Kafka (async events)                                           β”‚
β”‚            β–Ό                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚                    APACHE KAFKA                              β”‚            β”‚
β”‚  β”‚  Topics:                                                     β”‚            β”‚
β”‚  β”‚  β€’ products.product-created.v1  (Products β†’ Inventory)       β”‚            β”‚
β”‚  β”‚  β€’ inventory.stock-reserved.v1  (Inventory β†’ Orders)         β”‚            β”‚
β”‚  β”‚  β€’ inventory.low-stock.v1       (Inventory β†’ Products)       β”‚            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚                                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      DATA LAYER                                              β”‚
β”‚                            β”‚                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚  β”‚   PostgreSQL    β”‚  β”‚    Redis    β”‚  β”‚   H2 In-Memory  β”‚                  β”‚
β”‚  β”‚   (Port 5432)   β”‚  β”‚ (Port 6379) β”‚  β”‚ (Orders/Inv)    β”‚                  β”‚
β”‚  β”‚                 β”‚  β”‚             β”‚  β”‚                 β”‚                  β”‚
β”‚  β”‚ β€’ Products DB   β”‚  β”‚ β€’ API Cache β”‚  β”‚ β€’ Dev/Test DB   β”‚                  β”‚
β”‚  β”‚ β€’ Persistent    β”‚  β”‚ β€’ Sessions  β”‚  β”‚ β€’ Fast Startup  β”‚                  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚                                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 Key Design Decisions

Why This Architecture?

Decision Rationale Enterprise Benefit
gRPC for sync operations Stock reservation requires immediate consistency Sub-millisecond latency, type-safe contracts, bidirectional streaming ready
Kafka for async events Decoupled services, event replay, audit trail Horizontal scaling, fault tolerance, event sourcing ready
Redis caching Reduce database load on high-traffic endpoints 10-100x faster reads, distributed cache for multi-instance
Shared Protobuf contracts Single source of truth for service interfaces No API drift, generated clients, versioned schemas
PostgreSQL + H2 hybrid Production-ready persistence + fast dev cycle Real DB for catalog, in-memory for rapid iteration

Service Boundaries (Domain-Driven Design)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    PRODUCTS     β”‚     β”‚     ORDERS      β”‚     β”‚   INVENTORY     β”‚
β”‚    BOUNDED      β”‚     β”‚    BOUNDED      β”‚     β”‚    BOUNDED      β”‚
β”‚    CONTEXT      β”‚     β”‚    CONTEXT      β”‚     β”‚    CONTEXT      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Owns:           β”‚     β”‚ Owns:           β”‚     β”‚ Owns:           β”‚
β”‚ β€’ Product name  β”‚     β”‚ β€’ Order status  β”‚     β”‚ β€’ Stock levels  β”‚
β”‚ β€’ Description   β”‚     β”‚ β€’ Customer      β”‚     β”‚ β€’ Reservations  β”‚
β”‚ β€’ Price         β”‚     β”‚ β€’ Line items    β”‚     β”‚ β€’ Thresholds    β”‚
β”‚ β€’ Catalog data  β”‚     β”‚ β€’ Totals        β”‚     β”‚ β€’ Availability  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ›  Tech Stack

Backend

Technology Version Purpose
Java 17 LTS Core language with modern features (records, sealed classes, pattern matching)
Spring Boot 3.x Application framework, dependency injection, auto-configuration
Spring Data JPA 3.x Repository pattern, Hibernate ORM
Spring Security 6.x JWT authentication, role-based access control
Spring Kafka 3.x Event-driven messaging
gRPC Java 1.62 High-performance RPC framework
Protobuf 3.25 Schema-first API contracts
PostgreSQL 16 Production database (products catalog)
H2 2.x In-memory database (orders, inventory for dev)
Redis 7 Distributed caching layer

Frontend

Technology Version Purpose
Vue 3 3.x Reactive UI with Composition API
React 18 Component-based UI with hooks
Vite 5.x Lightning-fast build tool
Redux Toolkit 2.x State management (React)
TailwindCSS 3.x Utility-first styling

Infrastructure

Technology Purpose
Docker Compose Local development orchestration
Apache Kafka Event streaming platform
Maven Build automation, dependency management

πŸ“¦ Service Breakdown

1. Products Service (Port 8080)

Responsibilities: Product catalog management, caching, authentication

Key Features:

  • βœ… Full CRUD with pagination, sorting, search
  • βœ… JWT authentication (HS256, 24h expiry)
  • βœ… Redis caching with @Cacheable, @CacheEvict, @CachePut
  • βœ… Publishes ProductCreatedEvent to Kafka
  • βœ… Consumes LowStockEvent for dashboard projection

API Endpoints:

GET    /api/products                    # List all (+ pagination)
GET    /api/products/{id}               # Get single product
POST   /api/products                    # Create (requires JWT)
PUT    /api/products/{id}               # Full update
PATCH  /api/products/{id}               # Partial update
DELETE /api/products/{id}               # Delete
GET    /api/products/search?keyword=x   # Full-text search
POST   /api/auth/login                  # Get JWT token
POST   /api/auth/register               # Create user

2. Orders Service (Port 8081)

Responsibilities: Order lifecycle, stock reservation orchestration

Key Features:

  • βœ… Order creation with line items
  • βœ… gRPC client calls Inventory for stock reservation
  • βœ… Status transitions: CREATED β†’ RESERVED β†’ CANCELLED
  • βœ… Publishes order events to Kafka

API Endpoints:

GET    /api/orders                      # List all orders
GET    /api/orders/{id}                 # Get single order
POST   /api/orders                      # Create order
POST   /api/orders/{id}/reserve         # Reserve stock (gRPC β†’ Inventory)
POST   /api/orders/{id}/cancel          # Cancel order

gRPC Flow (Reserve Stock):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     gRPC (sync)      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Orders    β”‚ ─────────────────▢   β”‚  Inventory   β”‚
β”‚   Service    β”‚   ReserveStock()     β”‚   Service    β”‚
β”‚              β”‚ ◀─────────────────   β”‚              β”‚
β”‚              β”‚   Success/Fail       β”‚              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3. Inventory Service (Port 8082 REST, Port 9090 gRPC)

Responsibilities: Stock management, reservation logic, low-stock alerts

Key Features:

  • βœ… gRPC server for synchronous stock reservation
  • βœ… Atomic stock updates with optimistic locking
  • βœ… Low-stock threshold alerts (publishes to Kafka)
  • βœ… Consumes ProductCreatedEvent to auto-create stock entries

gRPC Contract (contracts/src/main/proto/inventory.proto):

service InventoryService {
  rpc ReserveStock(ReserveStockRequest) returns (ReserveStockResponse);
}

message ReserveStockRequest {
  int64 order_id = 1;
  repeated ReserveItem items = 2;
}

message ReserveStockResponse {
  bool reserved = 1;
  string reason = 2;
}

πŸ”„ Communication Patterns

Pattern 1: Synchronous (gRPC) - Stock Reservation

Use case: Stock reservation requires immediate consistency

User β†’ Orders Service β†’ gRPC β†’ Inventory Service β†’ Response
                    (blocking, ~50ms)

Why gRPC?

  • Type-safe contracts (Protobuf)
  • ~10x faster than REST
  • Streaming-ready for future features

Pattern 2: Asynchronous (Kafka) - Event Propagation

Use case: Notify services after state changes

Products Service  ──ProductCreatedEvent──▢  Kafka  ──▢  Inventory Service
Inventory Service ──LowStockEvent────────▢  Kafka  ──▢  Products Service

Why Kafka?

  • Services remain decoupled
  • Events can be replayed
  • Multiple consumers possible

Pattern 3: Caching (Redis)

Use case: High-traffic read endpoints

First request:  Cache MISS β†’ PostgreSQL β†’ Store in Redis β†’ Return
Second request: Cache HIT  β†’ Return from Redis (microseconds)

πŸš€ Quick Start

Prerequisites

  • Docker Desktop
  • Java 17+
  • Node.js 20+

One-Command Start

# Clone the repo
git clone https://github.com/aszender/java-spring-Guide.git
cd java-spring-Guide

# Start everything (Postgres + Kafka + Redis + services + UIs)
WITH_KAFKA=1 WITH_REDIS=1 ./dev.sh up

# Check status
./dev.sh status

# Stop everything
./dev.sh down

Startup Options

Command What it starts
./dev.sh up Basic mode (Postgres + services + UIs)
WITH_KAFKA=1 ./dev.sh up + Kafka event streaming
WITH_REDIS=1 ./dev.sh up + Redis caching
WITH_KAFKA=1 WITH_REDIS=1 ./dev.sh up Full production-like setup

Access Points

Service URL
Vue UI http://localhost:5173
React UI http://localhost:5174
Products API http://localhost:8080/api/products
Orders API http://localhost:8081/api/orders
Inventory API http://localhost:8082/api/inventory/stock

πŸ“– API Documentation

Authentication Flow

# 1. Login to get JWT token
curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123"}'

# 2. Use token for protected endpoints
curl -X POST http://localhost:8080/api/products \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"MacBook Pro","description":"16-inch","price":2499.99}'

Complete Order Flow (E2E)

# Step 1: Create a product (triggers Kafka β†’ Inventory creates stock)
curl -X POST http://localhost:8080/api/products \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"iPhone 15","price":999.99}'

# Step 2: Check inventory was auto-created
curl http://localhost:8082/api/inventory/stock

# Step 3: Create an order
curl -X POST http://localhost:8081/api/orders \
  -H "Content-Type: application/json" \
  -d '{"customerName":"John Doe","items":[{"productId":1,"quantity":2,"unitPrice":999.99}]}'

# Step 4: Reserve stock (gRPC call)
curl -X POST http://localhost:8081/api/orders/1/reserve

# Step 5: Check order status
curl http://localhost:8081/api/orders/1

πŸ§ͺ Testing Strategy

Test Pyramid Implementation

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚   E2E     β”‚  ← Manual testing via curl/UI
                    β”‚  (few)    β”‚
               β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”
               β”‚   Integration       β”‚  ← @SpringBootTest + @Transactional
               β”‚   (some)            β”‚
          β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”
          β”‚         Unit Tests            β”‚  ← @ExtendWith(MockitoExtension)
          β”‚         (many)                β”‚     @WebMvcTest
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Products Service Test Suite

Located in products-service/src/test/java/

Test Class Type What it Tests
ProductServiceTest Unit Service layer logic with mocked repository
ProductControllerWebMvcTest Slice REST endpoints with @WebMvcTest + MockMvc
ProductRepositoryTest Integration JPA queries with real database (@SpringBootTest)

Run Tests

# Run all tests (products-service)
cd products-service && ./mvnw test

# Run with verbose output
./mvnw test -Dtest=ProductServiceTest

# Run only unit tests (fast)
./mvnw test -Dgroups="unit"

# Run all services tests
./mvnw test -pl products-service,orders-service,inventory-service

Testing Tools & Frameworks

Tool Purpose
JUnit 5 Test framework with @Test, @BeforeEach, @DisplayName
Mockito Mocking dependencies (@Mock, @InjectMocks, when().thenReturn())
AssertJ Fluent assertions (assertThat(x).isEqualTo(y))
MockMvc Test REST controllers without starting server
@SpringBootTest Full integration tests with real beans
@WebMvcTest Slice test for web layer only
@DataJpaTest Slice test for repository layer
H2 In-memory database for fast integration tests

Test Coverage Focus

  • βœ… Happy path - CRUD operations work correctly
  • βœ… Edge cases - Not found, validation errors
  • βœ… Exception handling - ProductNotFoundException thrown appropriately
  • βœ… Repository queries - Custom JPQL/native queries return expected results

πŸ–₯ Frontend Applications

Vue 3 (frontVUE/products-ui)

  • Composition API with <script setup>
  • Reactive Store pattern (singleton module)
  • Composables for reusable logic
  • Pages: Products, Orders, Inventory

React 18 (frontReact/products-react)

  • Redux Toolkit for state management
  • Custom Hooks wrapping Redux
  • Feature-based folder structure
  • Pages: Products, Orders, Inventory

πŸ“ Project Structure

java-spring/
β”œβ”€β”€ products-service/          # Product catalog + Auth + Cache
β”œβ”€β”€ orders-service/            # Order management + gRPC client
β”œβ”€β”€ inventory-service/         # Stock management + gRPC server
β”œβ”€β”€ contracts/                 # Shared Protobuf definitions
β”œβ”€β”€ frontVUE/products-ui/      # Vue 3 frontend
β”œβ”€β”€ frontReact/products-react/ # React 18 frontend
β”œβ”€β”€ basic/                     # Java fundamentals demos
β”œβ”€β”€ docker-compose.yml         # Infrastructure
β”œβ”€β”€ dev.sh                     # Startup script
└── pom.xml                    # Parent Maven POM


βš™οΈ Error Handling, Validation & Logging

Global Error Handling

  • Centralized with @RestControllerAdvice (GlobalExceptionHandler)
  • Handles validation errors, not found, bad JSON, data integrity, and unexpected exceptions
  • Returns structured JSON error responses (status, message, path, validation details)

Validation

  • Uses Jakarta Bean Validation (@Valid, @NotNull, etc.) on DTOs and controller inputs
  • Automatic validation of incoming requests
  • Validation errors are caught and returned as clear API error responses

Logging

  • Spring Boot logging enabled (Logback)
  • Log levels set in application.properties (INFO for root, DEBUG for web)
  • All requests, errors, and stack traces are logged for troubleshooting

πŸš€ Future Enhancements

Planned Production Deployment

This project currently runs locally with Docker Compose. For production deployment, the architecture would include:

Backend Services

  • ECS/Fargate: Containerized microservices with auto-scaling
  • RDS PostgreSQL: Multi-AZ deployment for high availability
  • ElastiCache Redis: Distributed caching layer
  • MSK (Managed Kafka): Managed event streaming
  • Application Load Balancer: Traffic distribution across service instances
  • ECR: Private container registry

Frontend Applications

  • S3 + CloudFront: Static site hosting with global CDN
    • Vue/React build artifacts deployed to S3 buckets
    • CloudFront for edge caching and HTTPS
    • Route 53 for custom domain management
    • Reduced latency with edge locations worldwide
  • API Gateway (optional): Single entry point for backend APIs with rate limiting and authentication

CI/CD Pipeline (Jenkins)

pipeline {
    stages {
        stage('Backend Build & Test') {
            steps {
                sh './mvnw clean test package'
            }
        }
        stage('Frontend Build') {
            steps {
                sh 'cd frontVUE && npm run build'
                sh 'cd frontReact && npm run build'
            }
        }
        stage('Deploy Frontend to S3') {
            steps {
                sh 'aws s3 sync frontVUE/dist/ s3://products-vue-app/'
                sh 'aws s3 sync frontReact/dist/ s3://products-react-app/'
                sh 'aws cloudfront create-invalidation --distribution-id XXX'
            }
        }
        stage('Deploy Backend to ECS') {
            steps {
                sh 'docker build -t products-service .'
                sh 'docker push ${ECR_REPO}/products-service:${BUILD_NUMBER}'
                sh 'aws ecs update-service --cluster prod --service products --force-new-deployment'
            }
        }
    }
}

System Design Considerations

Scalability:

  • Stateless services enable horizontal scaling via ECS auto-scaling groups
  • CloudFront CDN reduces backend load for static assets
  • Database read replicas for Products service (read-heavy workload)
  • Kafka topic partitioning for parallel event processing
  • Redis cluster mode for distributed caching

Security:

  • VPC isolation for backend services (private subnets)
  • Security groups restricting inter-service communication
  • S3 bucket policies with CloudFront Origin Access Identity (OAI)
  • Secrets Manager for database credentials and API keys
  • WAF on CloudFront for DDoS protection

Reliability:

  • Multi-AZ RDS deployment (automatic failover)
  • ECS service auto-recovery on health check failures
  • Circuit breakers (Resilience4j) for fault isolation
  • Kafka consumer groups with retry logic and dead letter queues
  • CloudWatch alarms for proactive monitoring

Cost Optimization:

  • ECS Fargate Spot instances for non-critical workloads
  • S3 lifecycle policies for log retention
  • CloudFront caching reduces origin requests
  • RDS reserved instances for predictable workloads

Monitoring & Observability

  • CloudWatch Logs: Centralized logging for all services
  • CloudWatch Metrics: CPU, memory, request latency dashboards
  • X-Ray: Distributed tracing across microservices
  • Alarms: Automated alerts for error rates, latency spikes, low disk space

πŸ“ License

MIT License


πŸ‘€ Author

Andres Gonzalez

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published