Shop Microservers
E-commerce platform built with a microservices architecture: authentication, product catalog, shopping cart, and order processing, orchestrated behind an Nginx gateway and deployed using Docker Compose
Shop Microservers is a full-stack e-commerce application designed to demonstrate a real-world, decoupled microservices architecture. Each business domain (auth, catalog, cart, orders) lives in its own service, with its own database and its own deployment lifecycle, while a single gateway exposes a cohesive HTTP interface to the frontend.
Architecture and Tech Stack
Core Architecture
- Pattern: Microservices with database-per-service (each service owns its data).
- Gateway: Nginx as a reverse proxy and single entry point (port 80).
- Communication: Internal HTTP over a Docker bridge network (
shop), using service names as hostnames. - Orchestration: Docker Compose with health checks and health-based dependencies (
condition: service_healthy). - API contract: Uniform
{ success, data, error }response across all services.
Layered Diagram
Services and Responsibilities
| Route | Service | Port | Storage | Responsibility |
| `/api/auth/` | **auth** | 3004 | `auth_db` (PG) | Registration, login, JWT issuance |
| `/api/catalog/` | **catalog** | 3001 | `catalog_db`(PG) | Product listing and stock management |
| `/api/cart/` | **cart** | 3002 | `redis` | Ephemeral per-user cart (7-day TTL) |
| `/api/orders/` | **orders** | 3003 | `orders_db`(PG) | Checkout: validate stock → decrement → persist order → clear cart |
| `/` | **frontend** | 3000 | — | Next.js App Router (SPA, JWT in `localStorage`) |
8 containers in total: gateway, frontend, 4 microservices, 3 PostgreSQL, and 1 Redis.
Tech Stack
- Backend: Node.js + TypeScript, Express, Prisma ORM, Zod (validation).
- Frontend: Next.js 15 (App Router), React 19, Tailwind CSS 3, Radix UI, lucide-react.
- Databases: PostgreSQL 16 (auth, catalog, orders — one per service) and Redis 7 (cart).
- Gateway: Nginx (reverse proxy).
- Orchestration: Docker Compose.
Key Features
True database-per-service
Every stateful service has its own PostgreSQL instance (auth_db, catalog_db, orders_db), removing shared-database coupling. The schema is applied via Prisma when each container starts.
Orchestrated checkout flow
The orders service orchestrates the purchase transaction:
- Reads the user's cart by calling cart (
fetchCart). - Decrements stock item by item by calling catalog (
decrementStock). - Persists the order with its items into
orders_db. - Clears the cart by calling cart (
clearCart).
Ephemeral Redis cart
The cart lives in Redis under the key cart:{userId} with a 7-day TTL and no disk persistence: lightweight, fast, and disposable by design.
Shared-secret JWT auth
The JWT_SECRET is shared via environment variable across auth, cart, and orders, so any service can verify tokens without calling back to auth.
Technical Highlights
- Gateway as the only surface: The frontend never calls services directly — everything goes through Nginx, routed by prefix (
/api/<service>/). - Cascading health checks: The gateway depends on all 4 microservices being healthy; each service waits for its database to be healthy before starting.
- Auto-seeded catalog: Seeds 12 products automatically on first boot (idempotent).
- Validation as a boundary: Zod validates input in each service before touching the database.
- Uniform error handling:
AppError+ error middleware → consistent{ success, data, error }responses.
Main Endpoints
| Service | Method & route (internal) | Description |
| auth | `POST /register` | Create user and return JWT |
| auth | `POST /login` | Authenticate and return JWT |
| catalog | `GET /` | List products |
| catalog | `GET /:id` | Product detail |
| catalog | `PATCH /:id/stock` | Adjust stock (internal use) |
| cart | `GET /` | Get the user's cart |
| cart | `POST /items` | Add an item |
| cart | `DELETE /items/:productId` | Remove an item |
| cart | `DELETE /` | Empty the cart |
| orders | `GET /` | List the user's orders |
| orders | `GET /:id` | Order detail |
| orders | `POST /` | Checkout (create the order) |
Data Model
- auth_db →
User(id, email, passwordHash, createdAt). - catalog_db →
Product(id, name, price, imageUrl, stock, category). - orders_db →
Order(statusPENDING → CONFIRMED → SHIPPED → DELIVERED / CANCELLED) andOrderItem. - redis → per-user carts, no persistence.
How to Run
The app becomes available at http://localhost (or http://localhost:${GATEWAY_PORT}).
Project Structure
Notes
This report reflects the current architecture with independent databases per service (auth, catalog, and orders), internal HTTP communication over Docker, and an Nginx gateway as the single entry point. The design emphasizes decoupling, health checks, and a uniform API contract across all services.
ShopFlow — Luis Felipe Giraldo Ortega