This repository showcases a Modular Monolith implementation of borrowing books in a library with Spring Boot, Spring Modulith and Domain Driven Design principles.
The code is explained in a series of blog posts.
- Building Modular Monolith Applications with Spring Boot and Domain Driven Design - First attempt at building a Modular Monolith code with only Spring Boot and DDD (does not use Spring Modulith). The code is available in branch part-1-ddd-solution.
- Improving Modular Monolith Applications with Spring Modulith - In this blog, we rethink the domain model and apply eventual consistency with Spring Modulith to make the application easier to test, self-documenting and more maintainable. The code is available in branch part-2-spring-modulith and
main
. - TBA - Further improvements with Hexagonal architecture.
- JDK 21
- Spring Boot 3.2
- The library consists of thousands of books. There can be multiple copies of the same book.
- Before being included in the library, every book receives a barcode stamped at the back or one of the end pages. This barcode number uniquely identifies the book.
- A patron of the library can make a request to place a book on hold by either locating the book in the library or directly going to the circulation desk and ask for a book by title. If book is available, the patron can proceed to checkout (collect) the book.
- The book is checked out for a fixed period of 2 weeks.
- To check in (return) the book, the patron can go to the circulation desk or drop it in the drop zone.
Run the application with the command: mvn spring-boot:run
.
Access the Swagger UI at http://localhost:8080/swagger-ui.html
curl -X POST -H Content-Type:application/json http://localhost:8080/catalog/books \
-d '{"title":"Sapiens","catalogNumber":"12345","isbn":"9780062316097","author":"Yuval Noah Harari"}' | jq
Response:
{
"id": 1,
"title": "Sapiens",
"catalogNumber": {
"barcode": "12345"
},
"isbn": "9780062316097",
"author": {
"name": "Yuval Noah Harari"
}
}
curl -X POST -H Content-Type:application/json http://localhost:8080/borrow/loans \
-d '{"barcode": "12345", "patronId": 1}' | jq
Response:
{
"id": 1,
"bookBarcode": "12345",
"patronId": 1,
"dateOfHold": "2023-12-28",
"dateOfCheckout": null,
"holdDurationInDays": 3,
"loanDurationInDays": 0,
"dateOfCheckin": null,
"status": "HOLDING"
}
curl -X POST http://localhost:8080/borrow/loans/1/checkout | jq
Response:
{
"id": 1,
"bookBarcode": "12345",
"patronId": 1,
"dateOfHold": "2023-12-28",
"dateOfCheckout": "2023-12-28",
"holdDurationInDays": 3,
"loanDurationInDays": 14,
"dateOfCheckin": null,
"status": "ACTIVE"
}
curl -X POST http://localhost:8080/borrow/loans/1/checkin | jq
Response:
{
"id": 1,
"bookBarcode": "12345",
"patronId": 1,
"dateOfHold": "2023-12-28",
"dateOfCheckout": "2023-12-28",
"holdDurationInDays": 3,
"loanDurationInDays": 14,
"dateOfCheckin": "2023-12-28",
"status": "COMPLETED"
}