- Overview
- Prerequisites
- Getting Started
- Authentication
- API Endpoints
- Database Schema
- Caching
- AOP (Aspect-Oriented Programming)
- Running Tests
- Contribution
- Contact
The Library Management System is a Spring Boot application designed to manage library operations, including managing books, patrons, and borrowing records. The system includes secure API endpoints for various CRUD operations.
- Java 20 or later
- Maven 3.6+
- Spring Boot 3.3.2
- MySQL
- Postman or any API testing tool (optional)
git clone https://github.com/AhmedLotfy02/LibraryManagementSystem.git
cd LibraryManagementSystem
Update the application.properties
file with your database configuration:
spring.datasource.url=jdbc:mysql://localhost:3306/library_db
spring.datasource.username=your_db_username
spring.datasource.password=your_db_password
spring.jpa.hibernate.ddl-auto=update
Use Maven to build and run the application:
mvn clean install
mvn spring-boot:run
The application uses JWT for authentication. To access secured endpoints, you need to include the JWT token in the Authorization
header as a Bearer token.
Example:
Authorization: Bearer your_jwt_token
- Use the
/authenticate
endpoint to get a JWT token by providing valid user credentials. - Include the token in the
Authorization
header for subsequent API requests.
The application will start on http://localhost:8081
.
There is a postman collection contains all api documentations and requests in the repo "Library Management System APIs.postman_collection.json"
Endpoint: /authenticate
Method: POST
Description: Authenticates a user and returns a JWT token.
Note: for this demo use username = "admin" and password = "password" to access all APIs.
Request Body:
{
"username": "admin",
"password": "password"
}
Response:
{
"token": "jwt_token"
}
Endpoint: /api/books
Method: GET
Description: Retrieves a list of all books.
Response:
[
{
"id": 1,
"title": "Book Title",
"author": "Book Author",
"publicationYear": 2020,
"isbn": "1234567890"
}
]
Endpoint: /api/books/{id}
Method: GET
Description: Retrieves a book by its ID.
Response:
{
"id": 1,
"title": "Book Title",
"author": "Book Author",
"publicationYear": 2020,
"isbn": "1234567890"
}
Endpoint: /api/books
Method: POST
Description: Creates a new book.
Request Body:
{
"title": "New Book",
"author": "New Author",
"publicationYear": 2021,
"isbn": "0987654321"
}
Response:
{
"id": 2,
"title": "New Book",
"author": "New Author",
"publicationYear": 2021,
"isbn": "0987654321"
}
Endpoint: /api/books/{id}
Method: PUT
Description: Updates an existing book.
Request Body:
{
"title": "Updated Book",
"author": "Updated Author",
"publicationYear": 2022,
"isbn": "1122334455"
}
Response:
{
"id": 1,
"title": "Updated Book",
"author": "Updated Author",
"publicationYear": 2022,
"isbn": "1122334455"
}
Endpoint: /api/books/{id}
Method: DELETE
Description: Deletes a book by its ID.
Response:
HTTP Status 204 (No Content)
Endpoint: /api/patrons
Method: GET
Description: Retrieves a list of all patrons.
Response:
[
{
"id": 1,
"name": "John Doe",
"email": "[email protected]"
}
]
Endpoint: /api/patrons/{id}
Method: GET
Description: Retrieves a patron by its ID.
Response:
{
"id": 1,
"name": "John Doe",
"email": "[email protected]"
}
Endpoint: /api/patrons
Method: POST
Description: Creates a new patron.
Request Body:
{
"name": "Jane Doe",
"email": "[email protected]"
}
Response:
{
"id": 2,
"name": "Jane Doe",
"email": "[email protected]"
}
Endpoint: /api/patrons/{id}
Method: PUT
Description: Updates an existing patron.
Request Body:
{
"name": "John Smith",
"email": "[email protected]"
}
Response:
{
"id": 1,
"name": "John Smith",
"email": "[email protected]"
}
Endpoint: /api/patrons/{id}
Method: DELETE
Description: Deletes a patron by its ID.
Response:
HTTP Status 204 (No Content)
Endpoint: /api/borrow/{bookId}/patron/{patronId}
Method: POST
Description: Borrows a book for a patron.
Response:
{
"id": 1,
"bookId": 1,
"patronId": 1,
"borrowDate": "2023-01-01",
"returnDate": null
}
Endpoint: /api/return/{bookId}/patron/{patronId}
Method: PUT
Description: Returns a borrowed book.
Response:
{
"id": 1,
"bookId": 1,
"patronId": 1,
"borrowDate": "2023-01-01",
"returnDate": "2023-02-01"
}
The Library Management System database schema includes the following entities and relationships:
- Book: Represents the books in the library with attributes like
id
,title
,author
,publicationYear
, andisbn
. - BorrowingRecord: Represents the records of books borrowed by patrons with attributes like
id
,borrowDate
,returnDate
,patronId
, andbookId
. - Patron: Represents the library patrons with attributes like
id
,name
,email
, andphone
.
The relationships between these entities are as follows:
- A Book can have multiple BorrowingRecord entries (One-to-Many relationship).
- A BorrowingRecord is associated with one Book (Many-to-One relationship).
- A Patron can have multiple BorrowingRecord entries (One-to-Many relationship).
- A BorrowingRecord is associated with one Patron (Many-to-One relationship).
The application uses Spring Cache to improve performance by caching frequently accessed data.
Enable caching in your main application class:
@SpringBootApplication
@EnableCaching
public class LibraryManagementSystemApplication {
public static void main(String[] args) {
SpringApplication.run(LibraryManagementSystemApplication.class, args);
}
}
Annotate the service methods you want to cache:
@Service public class BookService {
@Cacheable("books") public List getAllBooks() { // method implementation }
@Cacheable(value = "books", key = "#id") public Book getBookById(Long id) { // method implementation } }
The application uses AOP for logging and performance monitoring.
Enable AOP in your main application class:
@SpringBootApplication
@EnableAspectJAutoProxy
public class LibraryManagementSystemApplication {
public static void main(String[] args) {
SpringApplication.run(LibraryManagementSystemApplication.class, args);
}
}
Create an aspect for logging:
@Aspect @Component public class LoggingAspect {
@Before("execution(* com.LibraryManagementSystem.demo.service..(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("Executing method: " + joinPoint.getSignature().getName()); }
@After("execution(* com.LibraryManagementSystem.demo.service..(..))") public void logAfter(JoinPoint joinPoint) { System.out.println("Completed method: " + joinPoint.getSignature().getName()); }
@Around("execution(* com.LibraryManagementSystem.demo.service..(..))") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); Object result = joinPoint.proceed(); long elapsedTime = System.currentTimeMillis() - start; System.out.println("Method " + joinPoint.getSignature().getName() + " executed in " + elapsedTime + " ms"); return result; } }
The project includes unit tests for the controllers, services, and utilities. These tests ensure that the application logic works correctly.
These tests validate the functionality of the API endpoints:
- shouldReturnBookById: Tests the retrieval of a book by its ID.
- shouldReturnAllBooks: Tests the retrieval of all books.
- shouldAddBook: Tests the addition of a new book.
- shouldUpdateBook: Tests the update of an existing book.
- shouldDeleteBook: Tests the deletion of a book by its ID.
These tests validate the business logic of the services:
- getAllBooks: Tests the retrieval of all books.
- getBookById: Tests the retrieval of a book by its ID.
- addBook: Tests the addition of a new book.
- updateBook: Tests the update of an existing book.
- deleteBook: Tests the deletion of a book by its ID.
These tests validate the functionality of the JWT token utility:
- testGenerateToken: Tests the generation of a JWT token.
- testValidateToken: Tests the validation of a JWT token.
- testGetUsernameFromToken: Tests the extraction of the username from a JWT token.
- testIsTokenExpired: Tests the expiration check of a JWT token.
mvn test
Feel free to fork this repository and contribute by submitting pull requests. Make sure to follow the project's coding standards and include tests for new features.
For any questions or support, please open an issue on GitHub or contact the repository owner at [email protected].