A secure, enterprise-grade Book Management & Circulation RESTful API built with Java 17, Spring Boot 3, and Spring Security 6. The system enforces stateless JWT (JSON Web Token) authentication, granular Role-Based Access Control (RBAC), transactional book lending/reservation workflows, and custom centralized exception handling.
[ Client Request ] ───► [ JwtAuthFilter ] ───► [ SecurityContextHolder ]
│
Validates JWT Signature
│
▼
[ Method Security: @PreAuthorize ]
├── Has 'ROLE_ADMIN' ───► Book Catalog CRUD / User Audit
└── Has 'ROLE_CUSTOMER' ─► Borrow / Reserve / Review
│
▼
[ Service Layer Transaction ]
├── @Transactional State Transitions
├── Reserve Queue Prioritization
└── History Audit Logging
│
▼
[ Spring Data JPA / MySQL ]
- Spring Security 6 & Stateless JWT:
- Intercepts requests via
JwtAuthFilterextendingOncePerRequestFilter. - Validates HMAC-SHA256 signed tokens and populates
SecurityContextHolder. - Role separation between administrative personnel (
ROLE_ADMIN) and standard members (ROLE_CUSTOMER).
- Intercepts requests via
- Transactional Circulation Engine:
- Manages complete lifecycle states:
AVAILABLE,BORROWED,RESERVED. - Prevents race conditions and double-borrowing with transactional boundary checks.
- Preserves historical audit records in
UserHistoryfor compliance and reading metrics.
- Manages complete lifecycle states:
- Centralized Global Exception Handling:
@ControllerAdvice(GlobalExceptionHandler) translating custom domain exceptions (BookNotAvailableException,NoReservationException,IdNotFoundException) into structured HTTP 400/404 responses.
- Data Transfer Object (DTO) Pattern:
- Leverages
ModelMapperfor clean segregation between internal JPA database entities and public REST API representations.
- Leverages
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
POST |
/user/register |
Register new user account with assigned role | Public |
POST |
/user/login |
Authenticate with credentials and receive JWT token | Public |
| Method | Endpoint | Description | Authorized Role |
|---|---|---|---|
POST |
/books/create |
Add new book to library catalog | ROLE_ADMIN |
PUT |
/books/update |
Modify book metadata or quantity | ROLE_ADMIN |
DELETE |
/books/delete |
Soft-delete book from circulation | ROLE_ADMIN |
GET |
/books/all |
List all books in the library | ROLE_ADMIN, ROLE_CUSTOMER |
| Method | Endpoint | Description | Authorized Role |
|---|---|---|---|
POST |
/books/{bookId}/borrow |
Borrow an available book copy | ROLE_CUSTOMER |
PUT |
/books/{bookId}/return |
Return a borrowed book | ROLE_CUSTOMER |
POST |
/books/{bookId}/reserve |
Place a reservation on a currently borrowed book | ROLE_CUSTOMER |
PUT |
/books/{bookId}/cancel-reservation |
Cancel active reservation | ROLE_CUSTOMER |
| Method | Endpoint | Description | Authorized Role |
|---|---|---|---|
POST |
/books/{bookId}/reviews/create |
Submit rating & review for a book | ROLE_CUSTOMER |
GET |
/books/{bookId}/reviews |
Fetch verified reviews for a title | ROLE_ADMIN, ROLE_CUSTOMER |
PUT |
/books/{bookId}/reviews/{reviewId}/update |
Edit existing review | ROLE_CUSTOMER |
- Java JDK 17
- Gradle 7+ (or use included
./gradlew) - MySQL 8.0+
In src/main/resources/application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/OnlineBookLibrary?createDatabaseIfNotExist=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=your_password
spring.jpa.hibernate.ddl-auto=update
server.port=8080./gradlew bootRunStep 1: Authenticate to Obtain Token
curl -X POST http://localhost:8080/user/login \
-H "Content-Type: application/json" \
-d '{
"username": "customer_user",
"password": "Password123!"
}'Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Step 2: Access Protected Endpoint
curl -X GET http://localhost:8080/books/all \
-H "Authorization: Bearer <YOUR_JWT_TOKEN>"Avijit Paul
- Role: Full Stack Software Engineer
- LinkedIn: linkedin.com/in/avijitpaulavi
- GitHub: github.com/X-AVI-X
- Email: avijit.paul.cs@gmail.com