Skip to content

Awvyyy/marketplaceAPI

Repository files navigation

Marketplace API

A learning REST API for a marketplace built with Spring Boot + MyBatis + PostgreSQL.

The project implements a basic marketplace flow:

  • user registration and login
  • viewing users, products, and orders
  • creating products
  • creating orders
  • updating order status
  • request validation
  • global error handling
  • password hashing with BCrypt

Tech Stack

  • Java 17
  • Spring Boot
  • Spring Web
  • Spring Security
  • Spring Validation
  • MyBatis
  • PostgreSQL
  • Gradle

Architecture

The project is split into layers:

  • controller — HTTP endpoints
  • service — business logic
  • mapper — database access through MyBatis
  • model — internal domain models
  • dto — API request/response objects
  • exceptions — custom exceptions and global exception handler
  • config — security and infrastructure configuration

Core Business Rules

A user can buy a product only if:

  • the product exists
  • there is enough stock
  • the buyer has enough balance
  • the buyer is not trying to buy their own product

When an order is created:

  • the buyer's balance is reduced
  • the product stock is reduced
  • a new order record is created

Order statuses:

  • ORDERED
  • SHIPPED
  • READY_TO_CLAIM
  • COMPLETED

Allowed transitions:

  • ORDERED -> SHIPPED
  • SHIPPED -> READY_TO_CLAIM
  • READY_TO_CLAIM -> COMPLETED

When an order becomes COMPLETED:

  • the seller receives the order amount
  • the seller's sales value is increased

Product creation:

  • the seller must exist
  • the price must be greater than 0
  • stock cannot be negative
  • if the seller has fewer than 2 sales, the product price is deducted from the seller's balance
  • if the seller has 2 or more sales, the product is created without balance deduction

Security

  • user passwords are stored as hashes using BCryptPasswordEncoder
  • login checks passwords through PasswordEncoder.matches(...)
  • Spring Security's default HTML login form is disabled
  • API endpoints are open for simpler development and testing

Validation

Request DTOs use jakarta.validation annotations such as:

  • @NotBlank
  • @NotNull
  • @Positive
  • @PositiveOrZero

Validation errors are returned as 400 Bad Request.


Error Handling

The project uses custom exceptions:

  • BadRequestException
  • NotFoundException
  • ConflictException

A global @ControllerAdvice returns structured JSON error responses.

Example:

{
  "timestamp": "2026-04-26T00:50:37.878Z",
  "status": 400,
  "error": "Bad Request",
  "message": "amount: must be greater than 0",
  "path": "/orders"
}

Database Structure

users

  • id
  • name
  • password_hash
  • balance
  • country
  • created_at
  • sales

products

  • id
  • seller_id
  • title
  • description
  • price
  • stock
  • created_at

orders

  • id
  • buyer_id
  • seller_id
  • product_id
  • order_price
  • destination
  • status
  • amount
  • created_at
  • updated_at

API Endpoints

Auth

POST /auth/registration

Register a new user.

Request:

{
  "name": "alex",
  "password": "alex123",
  "country": "EE"
}

Response:

{
  "id": 13,
  "name": "alex",
  "balance": 0,
  "country": "EE",
  "sales": 0
}

POST /auth/login

Login user.

Request:

{
  "name": "michael",
  "password": "michael123"
}

Users

GET /users

Get all users.

GET /users/{id}

Get user by id.

GET /users/{id}/orders

Get all orders where the user is the buyer.

GET /users/{id}/products

Get all products owned by the user as seller.


Products

GET /products

Get all products.

GET /products/{id}

Get product by id.

POST /products

Create a product.

Request:

{
  "sellerId": 1,
  "title": "Mechanical Keyboard",
  "description": "RGB keyboard",
  "price": 95.00,
  "stock": 5
}

Orders

GET /orders

Get all orders.

GET /orders/{id}

Get order by id.

POST /orders

Create an order.

Request:

{
  "buyerId": 2,
  "productId": 1,
  "destination": "EE",
  "amount": 1
}

PATCH /orders/{id}/status

Update an order status.

Request:

{
  "status": "SHIPPED"
}

Running the Project

1. Start PostgreSQL with Docker

For Windows cmd:

docker run --name marketplace-postgres -e POSTGRES_DB=marketplace_db -e POSTGRES_USER=marketplace_user -e POSTGRES_PASSWORD=marketplace_pass -p 5432:5432 -d postgres

Check that the container is running:

docker ps

2. Configure the database connection

src/main/resources/application.properties:

spring.application.name=demo1
spring.datasource.url=jdbc:postgresql://localhost:5432/marketplace_db
spring.datasource.username=marketplace_user
spring.datasource.password=marketplace_pass
spring.datasource.driver-class-name=org.postgresql.Driver
spring.sql.init.mode=always

3. Run the application

With Gradle:

./gradlew bootRun

or run Demo1Application directly from IntelliJ IDEA.


Database Initialization

On startup, the application uses:

  • schema.sql
  • data.sql

schema.sql creates the tables.
data.sql fills the database with test users, products, and orders.


Test Users

Example users from data.sql:

  • michael / michael123
  • agatha / agatha123
  • oliver / oliver123
  • sophia / sophia123
  • liam / liam123
  • emma / emma123

Error Examples

400 Bad Request

  • invalid request body
  • missing required field
  • amount <= 0
  • invalid status transition

404 Not Found

  • user not found
  • product not found
  • order not found

409 Conflict

  • username already exists
  • insufficient balance
  • insufficient stock
  • attempt to buy your own product

Possible Next Improvements

  • unit and integration tests
  • Swagger / OpenAPI
  • JWT authentication
  • pagination and filtering
  • moving auth logic into a separate AuthService
  • stricter role-based security
  • Docker Compose for app and database
  • CI/CD

Project Status

This is a learning project, but it already includes:

  • user, product, and order endpoints
  • marketplace business rules
  • request validation
  • centralized error handling
  • password hashing
  • transactional updates for balance and stock

About

Marketplace REST API with authentication, products, orders, validation and PostgreSQL persistence.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages