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

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages