BookFlow is a modern, scalable RESTful API designed for e-commerce book platforms. It handles the complete lifecycle of online sales: from secure stateless authentication to complex automated order processing.
This project showcases a production-ready backend built with stateless JWT authentication, role-based access control, and a well-structured layered architecture. It relies on Spring Data JPA for data access and Liquibase for database versioning.
- π οΈ Tech Stack
- π₯ Features
- π§± Architecture
- π§© Domain Model
- π Security
- π‘ API Endpoints
- π Example Workflow
- π¬ Video Demo
- π API Documentation
- π How to Run
| Layer | Technology |
|---|---|
| Language | Java 17 |
| Framework | Spring Boot |
| Security | Spring Security + JWT |
| Web | Spring Web (REST API) |
| Data Access | Spring Data JPA + Hibernate |
| Database | MySQL |
| In-Memory Database | H2 |
| Migrations | Liquibase |
| Mapping | MapStruct |
| Validation | Spring Validation |
| API Documentation | SpringDoc OpenAPI (SwaggerUI) |
| Testing | JUnit 5, Mockito |
| Containerization | Docker |
- π JWT-based authentication (stateless)
- π₯ Role-based access control (USER / ADMIN)
- π Full CRUD for books and categories
- π Shopping cart management
- π¦ Order creation and tracking
- π Pagination, filtering, and search
- π Swagger API documentation
- π³ Docker support
The project follows a layered architecture:
- Clear separation of concerns
- DTO layer instead of exposing entities to client
- MapStruct for mapping
- Low coupling between layers
- User
- Book
- Category
- ShoppingCart
- CartItem
- Order
- OrderItem
- User & ShoppingCart:
One-to-One(Each user has a dedicated cart) - ShoppingCart & CartItem:
One-to-Many(A cart can hold multiple items) - User & Order:
One-to-Many(One user can have an extensive order history) - Order & OrderItem:
One-to-Many(Each order tracks specific books and quantities) - Book & Category:
Many-to-Many(A book can belong to multiple genres, e.g., "Fantasy" and "Bestseller")
- JWT authentication
- Stateless session management
- Password hashing with BCrypt
- Custom UserDetailsService
- Method-level security with
@PreAuthorize
| Endpoints | HTTP Method | Description | Authentication |
|---|---|---|---|
| π Authentication | |||
/auth/registration |
POST | Create a new user account | None |
/auth/login |
POST | User login and receive JWT token | None |
| π Book management | |||
/books |
GET | Get all books (with pagination) | User / Admin |
/books/{id} |
GET | Get a book by ID | User / Admin |
/books/{id} |
PUT | Update a book by ID | ADMIN |
/books/{id} |
DELETE | Delete a book by ID | ADMIN |
/books/search |
GET | Search for books based on parameters | User / Admin |
| π Category management | |||
/categories |
GET | Get all categories (with pagination) | User / Admin |
/categories/{id} |
GET | Get a category by ID | User / Admin |
/categories/{id}/books |
GET | Get books by category ID | User / Admin |
| π Cart management | |||
/cart |
POST | Add book to shopping cart | User |
/cart/items/{id} |
PUT | Update the quantity of books in shopping cart | User |
/cart/items/{id} |
DELETE | Delete a book from shopping cart | User |
| π¦ Order management | |||
/orders |
POST | Create a new order | User |
/orders/{id} |
GET | Get an order by ID | User |
/orders/{id}/items |
GET | Get all items in an order | User |
/orders/{id} |
PATCH | Update order status (ADMIN) | ADMIN |
- Register a new user
- Login and receive JWT token
- Fetch books list
- Add a book to the cart
- Place an order
- View order history
- After starting the application:
http://localhost:8088/swagger-ui/index.html
- OpenAPI spec:
http://localhost:8088/v3/api-docs
git clone https://github.com/rmaksym1/bookflow-api.git
cd bookflow-apiCreate a .env file in the root directory based on .env.example.
Example:
# MySQL Database Configuration
MYSQLDB_ROOT_PASSWORD=db_password
MYSQLDB_USERNAME=db_username
MYSQLDB_DATABASE=db_name
MYSQLDB_LOCAL_PORT=3307 # Connect here if using a local DB client
MYSQLDB_DOCKER_PORT=3308
# Spring Boot Configuration
SPRING_LOCAL_PORT=8080 # The app will be available at this port
SPRING_DOCKER_PORT=8088
# Security Configuration
JWT_EXPIRATION=300000
JWT_SECRET=bookstoreproject1234567890wwwwww
# Debugging
DEBUG_PORT=5005Fill in the values according to your local MySQL setup and desired Spring Boot port.
If you are running the app inside Docker, your SPRING_DATASOURCE_URL in application.yml (or environment variables) should point to the database container name (usually db or mysql) and use the internal port (3306 or whatever is set in your compose file), not localhost.
docker-compose up --buildThis command will:
- Build the Spring Boot application Docker image
- Start MySQL container
- Start the application container
- Apply Liquibase database migrations automatically
Now app is available on:
http://localhost:8088
docker-compose downIf you prefer running locally:
- Start MySQL manually
- Create a database
- Update application.yml with local database credentials
- Run the following commands:
mvn clean install
mvn spring-boot:run