A Spring Boot learning project I built as a student to practice building a simple eCommerce backend. It covers authentication, products, categories, carts, orders, payments and image uploads with a clean layered structure.
- Spring Security with JWT (stateless auth) & OAuth2
- JPA/Hibernate relationships and repositories
- DTOs and request/response models
- Validation and global exception handling
- Building REST APIs with controllers and services
- Spring Boot 3.5.14
- Java 21
- Postgres
- Spring Security + JJWT
- OAuth2
- Redis
- Cloudinary
- Stripe
- Springdoc OpenAPI (Swagger UI)
- Lombok, ModelMapper, Jakarta Validation
config/application configurationcontroller/REST endpointsservice/business logicrepository/data accessentity/entitiesdto/API contractsmapper/entity–DTO mappingsecurity/JWT and security configexception/global error handling
All endpoints start with /api/v1.
Access levels:
(Public)— no authentication required(Authenticated)— any valid JWT token(Admin)— requiresROLE_ADMINrole
Auth (/auth)
POST /auth/register(Public)POST /auth/login(Public)
Products (/products)
GET /products(Public)GET /products/product/{productId}(Public)POST /products(Admin)PUT /products/product/{productId}(Admin)DELETE /products/product/{productId}(Admin)GET /products/by-brand-and-name(Public)GET /products/by-category-and-brand(Public)GET /products/by-name(Public)GET /products/by-brand(Public)GET /products/by-category(Public)GET /products/count/by-brand-and-name(Public)
Categories (/categories)
GET /categories(Public)POST /categories(Admin)GET /categories/{id}(Public)GET /categories/name/{name}(Public)DELETE /categories/{id}(Admin)PUT /categories/{id}(Admin)
Images (/images)
POST /images/upload(Admin)GET /images/view/{imageId}(Public)GET /images/download/{imageId}(Public)PUT /images/{imageId}(Admin)DELETE /images/{imageId}(Admin)
Carts (/carts)
GET /carts(Authenticated)DELETE /carts(Authenticated)GET /carts/total-price(Authenticated)
Cart Items (/cartItems)
POST /cartItems/add?productId={productId}&quantity={quantity}(Authenticated)PUT /cartItems/update/{productId}?quantity={quantity}(Authenticated)DELETE /cartItems/remove/{productId}(Authenticated)
Orders (/orders)
POST /orders(Authenticated)GET /orders(Admin)GET /orders/{orderId}(Authenticated)GET /orders/my-orders(Authenticated)DELETE /orders/{orderId}(Authenticated)PATCH /orders/{orderId}/order-status?status={status}(Admin)
Payments (/payments)
POST /payments/create-intent(Authenticated)GET /payments/{paymentId}(Authenticated)GET /payments/my-payments(Authenticated)GET /payments(Admin)PATCH /payments/{paymentId}/status?status={status}(Admin)DELETE /payments/{paymentId}/cancel(Authenticated)POST /payments/webhook(Public — Stripe webhook)
Users (/users)
GET /users/{userId}(Public)GET /users(Admin)POST /users(Public)PUT /users/{userId}(Admin)DELETE /users/{userId}(Admin)GET /users/by-email?email={email}(Public)
- Java 21
- Docker & Docker Compose
- Neon PostgreSQL database (free tier) or local postgreSQL driver
- Redis Cloud instance (free 30MB tier)
-
Clone the repo:
git clone <your-repo-url> cd ecommerce-backend
-
Copy
.env.exampleto.env.prodand fill in your credentials:cp .env.example .env.prod
-
Run with Docker Compose:
docker compose up --build
The app starts at
http://localhost:9000.
./mvnw spring-boot:runThe project includes ready-to-use Docker configuration:
| File | Purpose |
|---|---|
Dockerfile |
Multi-stage build — Maven compiles the app, then JRE runs the JAR |
.dockerignore |
Excludes .git/, target/, .env*, docs/ from the build context |
docker-compose.yml |
Runs the app with env vars loaded from .env.prod |
docker compose up --buildTo run in the background:
docker compose up --build -dThis app uses Redis for caching. Sign up for a free 30MB instance at redis.com/try-free.
Once created, configure these in .env.prod:
REDIS_HOST=your_redis_host
REDIS_PORT=your_redis_port
REDIS_PASSWORD=your_redis_passwordThe host and port are shown in your Redis Cloud dashboard under Public Endpoint.
- Push the repo to GitHub
- Render Dashboard → New Web Service → Connect your repo
- Runtime: Docker (auto-detected from
Dockerfile) - Set all environment variables from
.env.prodin Render's dashboard (do not commit them) - Port: 9000
- Deploy — your app will be live at
https://your-app.onrender.com - Swagger docs at
https://your-app.onrender.com/docs
Render builds using the Dockerfile — no docker-compose.yml needed on Render.
- This is my Spring Boot learning project.
- Swagger/OpenAPI docs are available at
/docs. - 7 test files: 4 unit (Mockito), 2 static analysis, 1 context load