A backend REST API for an e-commerce app — built with Spring Boot and Java. Handles users, products, carts, and orders with JWT-based login.
cartify/
├── src/
│ ├── main/
│ │ ├── java/com/ecommerce/sb_ecom/
│ │ │ ├── controller/
│ │ │ │ ├── AuthController.java
│ │ │ │ ├── CategoryController.java
│ │ │ │ ├── ProductController.java
│ │ │ │ ├── CartController.java
│ │ │ │ └── OrderController.java
│ │ │ ├── service/
│ │ │ │ ├── AuthService.java
│ │ │ │ ├── CategoryService.java
│ │ │ │ ├── ProductService.java
│ │ │ │ ├── CartService.java ◄── add to cart logic
│ │ │ │ └── OrderService.java ◄── place order logic
│ │ │ ├── repositories/
│ │ │ │ ├── UserRepository.java
│ │ │ │ ├── ProductRepository.java
│ │ │ │ ├── CartRepository.java
│ │ │ │ ├── CartItemRepository.java
│ │ │ │ └── OrderRepository.java
│ │ │ ├── security/
│ │ │ │ ├── WebSecurityConfig.java ◄── who can access what
│ │ │ │ ├── JwtUtils.java ◄── creates & reads tokens
│ │ │ │ └── JwtAuthFilter.java ◄── checks token on every request
│ │ │ ├── model/
│ │ │ │ ├── User.java
│ │ │ │ ├── Product.java
│ │ │ │ ├── Category.java
│ │ │ │ ├── Cart.java
│ │ │ │ ├── CartItem.java
│ │ │ │ ├── Order.java
│ │ │ │ ├── OrderItem.java
│ │ │ │ └── Payment.java
│ │ │ └── payload/
│ │ │ ├── request/
│ │ │ │ ├── LoginRequest.java
│ │ │ │ └── SignupRequest.java
│ │ │ └── response/
│ │ │ ├── UserInfoResponse.java
│ │ │ ├── ProductDTO.java
│ │ │ ├── CartDTO.java
│ │ │ └── OrderDTO.java
│ │ └── resources/
│ │ └── application.properties
│ └── test/
│ ├── java/com/ecommerce/sb_ecom/
│ │ └── AuthIntegrationTest.java
│ └── resources/
│ └── application-test.properties
├── pom.xml
└── README.md
Every request goes through these layers in order:
┌─────────────────────────────────────────────────────────────────┐
│ CLIENT (Browser) │
│ Cookie: ecommerce-jwt (HttpOnly) │
└────────────────────────────┬────────────────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────────────────────────────┐
│ SECURITY LAYER │
│ JwtAuthFilter ──► WebSecurityConfig │
│ Checks the JWT token on every incoming request │
└────────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ CONTROLLER LAYER │
│ AuthController │ ProductController │ CartController │
│ CategoryController │ OrderController │
│ Receives requests, sends back responses │
└────────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ SERVICE LAYER │
│ AuthService │ ProductService │ CartService │
│ CategoryService │ OrderService │
│ Where all the actual logic lives │
└────────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ REPOSITORY LAYER │
│ UserRepo │ ProductRepo │ CartRepo │ OrderRepo │
│ Talks to the database (Spring Data JPA) │
└────────────────────────────┬────────────────────────────────────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────────┐
│ PostgreSQL │ │ H2 In-Memory │
│ (when deployed) │ │ (when testing) │
└──────────────────────┘ └──────────────────────────┘
When you log in, the server gives you a token stored in a cookie. Your browser sends that cookie automatically on every request — so the server knows who you are without you logging in every time.
You Server
│ │
│── POST /api/auth/signin ──────►│
│ { username, password } │
│ │── checks your credentials
│ │── creates a JWT token (lasts 24h)
│◄── 200 OK ─────────────────── │
│ Set-Cookie: ecommerce-jwt │── saved in your browser
│ │
│── GET /api/carts ─────────────►│
│ (cookie sent automatically) │── reads the token, knows it's you
│◄── 200 OK ─────────────────── │── sends back your cart
┌─────────────┐
│ ADMIN │──── everything below +
└──────┬──────┘ manage categories
│ manage all products
│ view all orders
┌──────▼──────┐
│ SELLER │──── manage own products
│ (coming) │ (not built yet)
└──────┬──────┘
│
┌──────▼──────┐
│ USER │──── add to cart
│ │ place orders
└─────────────┘
┌─────────────┐ ┌──────────────┐ ┌───────────────┐
│ users │ │ products │ │ categories │
├─────────────┤ ├──────────────┤ ├───────────────┤
│ user_id PK │ │ product_id PK│──────►│ category_id PK│
│ username │ │ product_name │ │ category_name │
│ email │ │ description │ └───────────────┘
│ password │ │ quantity │
└──────┬──────┘ │ price │
│ │ special_price│
│ OneToOne └──────────────┘
▼
┌─────────────┐ ┌───────────────┐
│ carts │ │ cart_items │
├─────────────┤ ├───────────────┤
│ cart_id PK │──────►│ cart_item_id │
│ total_price │ │ cart_id FK │
└─────────────┘ │ product_id FK │
│ quantity │
│ price │
└───────────────┘
┌─────────────┐ ┌───────────────┐ ┌──────────────┐
│ orders │ │ order_items │ │ payments │
├─────────────┤ ├───────────────┤ ├──────────────┤
│ order_id PK │──────►│ order_item_id │ ◄────│ payment_id PK│
│ email │ │ order_id FK │ │ order_id FK │
│ order_status│ │ product_id FK │ │ payment_method│
│ total_amount│ │ quantity │ │ pg_status │
└─────────────┘ │ price │ └──────────────┘
└───────────────┘
| Method | Endpoint | Who | Description |
|---|---|---|---|
POST |
/api/auth/signup |
Anyone | Create an account |
POST |
/api/auth/signin |
Anyone | Log in, get JWT cookie |
| Method | Endpoint | Who | Description |
|---|---|---|---|
GET |
/api/public/products |
Anyone | Browse products |
GET |
/api/public/categories |
Anyone | Browse categories |
POST |
/api/admin/categories |
Admin | Add a category |
POST |
/api/admin/products |
Admin | Add a product |
PUT |
/api/admin/products/{id} |
Admin | Edit a product |
DELETE |
/api/admin/products/{id} |
Admin | Remove a product |
| Method | Endpoint | Who | Description |
|---|---|---|---|
POST |
/api/carts/products/{productId}/quantity/{qty} |
User | Add item to cart |
GET |
/api/carts |
User | See your cart |
PUT |
/api/cart/products/{productId}/quantity/{op} |
User | Change quantity |
DELETE |
/api/carts/{cartId}/product/{productId} |
User | Remove item |
| Method | Endpoint | Who | Description |
|---|---|---|---|
POST |
/api/order/users/payments/{method} |
User | Place an order |
GET |
/api/admin/orders |
Admin | See all orders |
Try all of these live at https://cartifybackend.up.railway.app/swagger-ui/index.html
You need Java 21, Maven 3.8+, and PostgreSQL installed.
# 1. Clone the repo
git clone https://github.com/your-username/cartify.git
cd cartify
# 2. Create the database
psql -U postgres -c "CREATE DATABASE sb_ecom;"
# 3. Set your environment variables
export DB_URL=jdbc:postgresql://localhost:5432/sb_ecom
export DB_USERNAME=postgres
export DB_PASSWORD=your_password
export JWT_SECRET=$(echo -n "your-secret" | base64)
# 4. Run it
mvn spring-boot:runApp will be running at http://localhost:8080
# application.properties
DB_URL=jdbc:postgresql://localhost:5432/sb_ecom
DB_USERNAME=postgres
DB_PASSWORD=your_password
# to generate this: echo -n "any-random-text" | base64
JWT_SECRET=your_base64_secret_hereTests run against an in-memory H2 database so you don't need PostgreSQL set up just to test.
mvn test # run everything
mvn test -Dtest=AuthIntegrationTest # just auth tests| Scenario | Endpoint | Expected |
|---|---|---|
| Register | POST /api/auth/signup |
200 OK |
| Login | POST /api/auth/signin |
200 OK + cookie set |
| Cookie check | Login response header | ecommerce-jwt present |
| Body check | Login response body | username returned |
- Fork this repo and clone it locally
- Create a branch —
git checkout -b feature/what-you-are-adding - Make your changes, then run
mvn testto make sure nothing broke - Commit with a short message —
git commit -m "feat: what you did" - Push and open a Pull Request against
main
Feel free to open an issue first if you're unsure about something.