The Online Book Store App is a robust and user-friendly Java web application designed to manage book inventory and facilitate online book purchases. This project showcases how modern Java frameworks and libraries can come together to create a scalable and efficient software solution.
The application includes user authentication, API documentation, database integrations, and controller-based functionalities tailored to enhance user experience. The project demonstrates strong coding practices, making it a great example for presenting technical proficiency.
- User Authentication: Secure user login and registration using Spring Security and JWT.
- RESTful API: Well-structured APIs for CRUD operations on books, users, and orders.
- Database Management: Integrated with MySQL and supported by Liquibase for database migrations.
- OpenAPI Documentation: Explore the API endpoints conveniently using Springdoc Swagger.
- Validation and Error Handling: Input validation with detailed error messages.
- Scalability: Modular and extendable architecture with Spring Boot's framework.
- Development Efficiency: Features hot reloading through Spring Boot DevTools.
This project leverages the following technologies and tools
- Java 17: The core programming language.
- Spring Framework (v3.4.1):
- Spring Boot
- Spring Data JPA
- Spring Security
- Spring MVC
- Database:
- MySQL Connector (JDBC): v9.0.0
- Liquibase (Database migration tool): v4.29.2
- API Documentation:
- SpringDoc OpenAPI & Swagger UI: v2.7.0
- JWT (io.jsonwebtoken): v0.12.6. JSON Web Tokens for authentication.
- Lombok: v1.18.36. Simplified Java development with reduced boilerplate.
- MapStruct: v1.5.5.Final. For converting entities to DTOs and vice versa.
- Docker Compose: v3.4.1. For containerized and simplified deployment.
- Additional tools like Maven for builds and Git for version control.
The Auth Controller handles registration and authentication processes for users.
- Endpoints:
- POST /auth/registration β Allows new users to sign up by providing their email, password, and personal details.
- POST /auth/login β Authenticates a user and provides a JWT for accessing protected endpoints.
The Book Controller manages the creation, retrieval, search, update, and deletion of books with role-based access control.
- Endpoints:
- GET /books β Retrieves a paginated list of all books.
Access: Accessible to users with the role
ROLE_USER
. - GET /books/{id} β Retrieves detailed information for a specific book by its ID.
Access: Accessible to users with the role
ROLE_USER
. - GET /books/search β Searches for books based on specific parameters (e.g., category, author) and returns a paginated list of results.
Access: Accessible to users with the role
ROLE_USER
. - POST /books β Creates a new book in the system.
Access: Restricted to administrators with the role
ROLE_ADMIN
. - PUT /books/{id} β Updates an existing book's details.
Access: Restricted to administrators with the role
ROLE_ADMIN
. - DELETE /books/{id} β Deletes a specific book by its ID.
Access: Restricted to administrators with the role
ROLE_ADMIN
.
- GET /books β Retrieves a paginated list of all books.
Access: Accessible to users with the role
Category Controller provides endpoints for managing book categories, including CRUD operations and listing books associated with specific categories. Access is role-based to ensure security.
- Endpoints:
- GET /categories β Retrieve a paginated list of all categories.
Access: Accessible to users with the role
ROLE_USER
. - GET /categories/{id} β Retrieve details of a specific category by its ID.
Access: Accessible to users with the role
ROLE_USER
. - GET /categories/{id}/books β Retrieves a paginated list of all books belonging to a specific category.
Access: Accessible to users with the role
ROLE_USER
. - POST /categories β Create a new category.
Access: Restricted to administrators with the role
ROLE_ADMIN
. - PUT /categories/{id} β Update an existing category by its ID.
Access: Restricted to administrators with the role
ROLE_ADMIN
. - DELETE /categories/{id} β Delete a category by its ID.
Access: Restricted to administrators with the role
ROLE_ADMIN
.
- GET /categories β Retrieve a paginated list of all categories.
Access: Accessible to users with the role
The Order Controller manages the creation, retrieval, and updating of orders and their items. It supports both user-specific operations and administrative tasks for managing orders.
- Endpoints:
- POST /orders β Places an order. Accessible to authenticated users with the role
ROLE_USER
. Example Use: Provide necessary details (e.g., book IDs, quantity) to create a new order. - GET /orders β Retrieve a paginated list of all orders placed by the currently logged-in user.
Accessible to
ROLE_USER
. - PATCH /orders/{id} β Update the status of an order (e.g., to "shipped" or "delivered").
Accessible only to administrators with the
ROLE_ADMIN
role. - GET /orders/{orderId}/items β Retrieve a detailed list of order items for a specific order by its ID. Provides a paginated response.
Accessible to the owner of the order (
ROLE_USER
). - GET /orders/{orderId}/items/{itemId} β Fetch details of a specific item from an order.
Accessible to the owner of the order (
ROLE_USER
).
- POST /orders β Places an order. Accessible to authenticated users with the role
The Shopping Cart Controller manages the retrieval, modification, and deletion of items in a user's shopping cart. It ensures that only authenticated users can interact with their shopping cart.
- Endpoints:
- GET /cart β Retrieve the shopping cart of the currently authenticated user.
Accessible to authenticated users with the role
ROLE_USER
. Example Use: View all items and their quantities in the shopping cart. - POST /cart β Add a book to the shopping cart.
Accessible to authenticated users with the role
ROLE_USER
. Example Use: Add a specific book to the shopping cart with the desired quantity. - PUT /cart/{cartItemId} β Update the details (e.g., quantity) of an existing item in the cart.
Accessible to authenticated users with the role
ROLE_USER
. Example Use: Modify the quantity of a specific item in the shopping cart. - DELETE /cart/{cartItemId} β Remove an item from the shopping cart by its ID.
Accessible to authenticated users with the role
ROLE_USER
. Example Use: Delete an item from the cart when it's no longer needed.
- GET /cart β Retrieve the shopping cart of the currently authenticated user.
Accessible to authenticated users with the role
Ensure the following are installed on your machine:
- Java: JDK 17+.
- Build Tool: Maven or Gradle (Maven used in this project).
- Docker version 20+
- Docker Compose version 2.5+
git clone [email protected]:chertiav/online-book-store-app.git
cd online-book-store-app
-
In the root directory of the project, create a new file named
.env
.
This file will store the environment variables necessary to configure the database and application. -
Add the following variables to the
.env
file based on the provided template:
MYSQLDB_USER=<your_database_username>
MYSQLDB_PASSWORD=<your_database_password>
MYSQLDB_DATABASE=online_book_store
MYSQL_LOCAL_PORT=3308
MYSQL_DOCKER_PORT=3306
JWT_EXPIRATION=3600000
JWT_SECRET=<your_jwt_secret>
SPRING_LOCAL_PORT=8088
SPRING_DOCKER_PORT=8080
DEBUG_PORT=5005
- Replace the placeholders
<your_database_username>
,<your_database_password>
, and<your_jwt_secret>
with actual values. For example:
MYSQLDB_USER=admin
MYSQLDB_PASSWORD=qwerty
JWT_SECRET=abcdefghijklmnopABCDEFGHIJKLMNOP12345678
- Descriptions of Required Variables:
MYSQLDB_USER
β The username for the MySQL database.MYSQLDB_PASSWORD
β Password for the MySQL database user.MYSQLDB_DATABASE
β The name of the database used by the application (defaults toonline_book_store
).JWT_SECRET
β A secure key used to sign JWT tokens. Ensure this is a strong and unique value.
- The variable
MYSQL_LOCAL_PORT
specifies the port used locally to connect to the database, whileMYSQL_DOCKER_PORT
specifies the port inside the Docker container. These generally do not need modification. SPRING_LOCAL_PORT
,SPRING_DOCKER_PORT
, andDEBUG_PORT
define the ports for the application and debugging and should match your local and containerized setup.
Make sure to save the .env
file and avoid committing it to version control to keep sensitive information secure.
-
Once the
.env
file is configured, navigate to the projectβs root directory using the terminal. -
Use the following command to start the application and all required services via Docker Compose:
docker compose up --build
-
What this does:
- This command builds the Docker images for the application and required services.
- It starts the application, database, and any other dependencies inside containers.
-
Wait for the services to start. You should see logs indicating that the application and database are running.
- If you are accessing the application locally (outside the container), use the port defined in
SPRING_LOCAL_PORT
. Since thecontext-path
is set to/api
, the application will be accessible at:
http://localhost:8088/api
- To view the Swagger API documentation, navigate to:
http://localhost:8088/api/swagger-ui/index.html
- If you are working inside a container, the application will be accessible on the port defined in
SPRING_DOCKER_PORT
. Use the following address:
http://localhost:8080/api
- Similarly, the Swagger documentation inside the container will be available at:
http://localhost:8080/api/swagger-ui/index.html
- The separation of ports (
SPRING_LOCAL_PORT
andSPRING_DOCKER_PORT
) allows you to work locally on one port and expose another port for Docker containers. - Ensure you are accessing the correct port depending on your working environment.
- Problem: Integrating the application with Docker Compose while ensuring smooth database connections.
- Solution: Used
spring-boot-docker-compose
starter dependency to simplify integration and manage service dependencies automatically.
- Problem: Updating the database schema consistently during development.
- Solution: Adopted Liquibase for schema versioning and included Liquibase scripts in
docker-compose
.
You can find a Postman collection in docs/online-book-store-app-api.postman_collection.json
. To use this:
- Import the file into Postman.
- Adjust Authorization headers (use JWT obtained from login endpoint).
- Test all exposed APIs such as authentication, book management, and more.
-
User - Role (Many to Many):
- A user can have multiple roles (e.g., ADMIN, USER).
- A role can belong to multiple users.
-
ShoppingCart - CartItem (One to Many):
- Each user has one shopping cart (ShoppingCart) containing several cart items (CartItem).
-
CartItem - Book (Many to One):
- Each cart item refers to a specific book.
-
Book - Category (Many to Many):
- A book can belong to multiple categories, and a category can have multiple books.
-
Order - OrderItems (One to Many):
- An order (Order) can have multiple items (OrderItem), where an item refers to a specific book.
-
Order - User (Many to One):
- Each order is created by a single user.
We welcome contributions to enhance the project! To contribute:
- Fork the repository.
- Create a branch:
git checkout -b new-feature
- Commit your changes:
git commit -m "Add new feature"
- Test your changes.
- Submit a pull request.
This project is licensed under the MIT License.
Feel free to reach out for feedback or questions:
- Email: [[email protected]]
- GitHub: GitHub Profile