Skip to content

julian-razif-figaro-workspaces/sample-web-api

Repository files navigation

Library Management API

A Spring Boot 4 REST API for managing a library's book inventory and member checkout operations.

Technology Stack

Component Version
Java JDK 25
Spring Boot 4.0.2
Spring Security 7.x
PostgreSQL 16+
H2 Database (dev/test)
JWT Authentication jjwt 0.12.6
Build Tool Maven

Features

  • Book Management (ADMIN): CRUD operations for library books
  • Member Checkout (MEMBER): Browse available books, checkout, and return
  • JWT Authentication: Secure token-based authentication
  • Role-Based Access Control: ADMIN and MEMBER roles
  • Pagination: All list endpoints support pagination
  • Validation: Comprehensive input validation

Project Structure

src/main/java/com/library/
├── LibraryManagementApplication.java    # Main entry point
├── application/                          # Application layer
│   ├── dto/                              # Data Transfer Objects
│   ├── mapper/                           # Entity-DTO mappers
│   └── service/                          # Business logic
├── domain/                               # Domain layer
│   ├── exception/                        # Custom exceptions
│   ├── model/                            # Entities and enums
│   └── repository/                       # Data access interfaces
├── infrastructure/                       # Infrastructure layer
│   ├── config/                           # Configuration classes
│   └── security/                         # JWT security
└── presentation/                         # Presentation layer
    ├── advice/                           # Exception handlers
    └── controller/                       # REST controllers

Getting Started

Prerequisites

  • JDK 25 or later
  • Maven 3.9+
  • PostgreSQL 16+ (for staging/production)

Running the Application

Development Profile

Run with H2 in-memory database, debug logging, and sample data:

# Unix/Linux/macOS
./mvnw spring-boot:run -Dspring-boot.run.profiles=dev

# Windows PowerShell
.\mvnw spring-boot:run "-Dspring-boot.run.profiles=dev"

# Windows Command Prompt
.\mvnw spring-boot:run -Dspring-boot.run.profiles=dev

The application will start on http://localhost:8080 with:

  • H2 in-memory database (data resets on restart)
  • Sample data pre-loaded (users and books)
  • H2 Console available at /h2-console
  • Debug logging enabled
  • SQL queries logged to console

Staging Profile

Run with PostgreSQL database and Flyway migrations:

# Unix/Linux/macOS
./mvnw spring-boot:run -Dspring-boot.run.profiles=staging

# Windows PowerShell
.\mvnw spring-boot:run "-Dspring-boot.run.profiles=staging"

Required environment variables:

# Unix/Linux/macOS
export DATABASE_URL=jdbc:postgresql://localhost:5432/library_staging
export DATABASE_USERNAME=your_username
export DATABASE_PASSWORD=your_password
export JWT_SECRET=your-256-bit-secret-key-for-staging
# Windows PowerShell
$env:DATABASE_URL="jdbc:postgresql://localhost:5432/library_staging"
$env:DATABASE_USERNAME="your_username"
$env:DATABASE_PASSWORD="your_password"
$env:JWT_SECRET="your-256-bit-secret-key-for-staging"

Features:

  • PostgreSQL database with Flyway migrations
  • Info-level logging
  • Connection pooling optimized for staging

Production Profile

Run with production-optimized settings:

# Unix/Linux/macOS
./mvnw spring-boot:run -Dspring-boot.run.profiles=prod

# Windows PowerShell
.\mvnw spring-boot:run "-Dspring-boot.run.profiles=prod"

# Using Java directly (recommended for production)
java -jar target/library-management-system-1.0.0-SNAPSHOT.jar --spring.profiles.active=prod

Required environment variables:

# Unix/Linux/macOS
export DATABASE_URL=jdbc:postgresql://localhost:5432/library_prod
export DATABASE_USERNAME=your_username
export DATABASE_PASSWORD=your_password
export JWT_SECRET=your-256-bit-secret-key-for-production
export SERVER_PORT=8080
# Windows PowerShell
$env:DATABASE_URL="jdbc:postgresql://localhost:5432/library_prod"
$env:DATABASE_USERNAME="your_username"
$env:DATABASE_PASSWORD="your_password"
$env:JWT_SECRET="your-256-bit-secret-key-for-production"
$env:SERVER_PORT="8080"

Features:

  • PostgreSQL database with Flyway migrations
  • Minimal logging (WARN level)
  • Optimized connection pooling
  • Graceful shutdown enabled
  • Virtual threads enabled for high concurrency

Default Users (Development)

Username Password Role
admin admin123 ADMIN
member member123 MEMBER

API Endpoints

Authentication

Method Endpoint Description Access
POST /api/v1/auth/login User login Public
POST /api/v1/auth/refresh Refresh token Public

Books (Admin Only)

Method Endpoint Description
POST /api/v1/books Create a new book
GET /api/v1/books List all books (paginated)
GET /api/v1/books/{id} Get book by ID
PUT /api/v1/books/{id} Update a book
DELETE /api/v1/books/{id} Delete a book

Available Books (Member Only)

Method Endpoint Description
GET /api/v1/books/available List available books

Query Parameters:

  • genre: Filter by genre (FICTION, NON_FICTION, SCIENCE, HISTORY, BIOGRAPHY, CHILDREN)
  • publicationYear: Filter by publication year
  • page: Page number (default: 0)
  • size: Page size (default: 20)

Checkouts (Member Only)

Method Endpoint Description
POST /api/v1/checkouts/books/{bookId} Checkout a book
POST /api/v1/checkouts/{checkoutId}/return Return a book
GET /api/v1/checkouts/history Get checkout history

Authentication

Login Request

POST /api/v1/auth/login
{
    "username": "member",
    "password": "member123"
}

Login Response

{
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "tokenType": "Bearer",
    "expiresIn": 3600
}

Using the Token

Include the access token in the Authorization header:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Example Requests

Create a Book (Admin)

# Unix/Linux/macOS (curl)
curl -X POST http://localhost:8080/api/v1/books \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "isbn": "978-0-06-112008-4",
    "title": "To Kill a Mockingbird",
    "author": "Harper Lee",
    "genre": "FICTION",
    "publicationYear": 1960,
    "totalCopies": 5
  }'
# Windows PowerShell
Invoke-RestMethod -Uri "http://localhost:8080/api/v1/books" `
  -Method POST `
  -Headers @{
    "Authorization" = "Bearer <admin-token>"
    "Content-Type" = "application/json"
  } `
  -Body '{
    "isbn": "978-0-06-112008-4",
    "title": "To Kill a Mockingbird",
    "author": "Harper Lee",
    "genre": "FICTION",
    "publicationYear": 1960,
    "totalCopies": 5
  }'

Browse Available Books (Member)

# Unix/Linux/macOS (curl)
curl "http://localhost:8080/api/v1/books/available?genre=FICTION&page=0&size=10" \
  -H "Authorization: Bearer <member-token>"
# Windows PowerShell
Invoke-RestMethod -Uri "http://localhost:8080/api/v1/books/available?genre=FICTION&page=0&size=10" `
  -Headers @{ "Authorization" = "Bearer <member-token>" }

Checkout a Book (Member)

# Unix/Linux/macOS (curl)
curl -X POST http://localhost:8080/api/v1/checkouts/books/{bookId} \
  -H "Authorization: Bearer <member-token>"
# Windows PowerShell
Invoke-RestMethod -Uri "http://localhost:8080/api/v1/checkouts/books/{bookId}" `
  -Method POST `
  -Headers @{ "Authorization" = "Bearer <member-token>" }

Return a Book (Member)

# Unix/Linux/macOS (curl)
curl -X POST http://localhost:8080/api/v1/checkouts/{checkoutId}/return \
  -H "Authorization: Bearer <member-token>"
# Windows PowerShell
Invoke-RestMethod -Uri "http://localhost:8080/api/v1/checkouts/{checkoutId}/return" `
  -Method POST `
  -Headers @{ "Authorization" = "Bearer <member-token>" }

Configuration

Environment Variables

Variable Description Default
SPRING_PROFILES_ACTIVE Active profile (dev/staging/prod) dev
SERVER_PORT Server port 8080
DATABASE_URL PostgreSQL connection URL -
DATABASE_USERNAME Database username -
DATABASE_PASSWORD Database password -
JWT_SECRET JWT signing secret (256+ bits) -
JWT_ACCESS_EXPIRATION Access token expiration (ms) 3600000
JWT_REFRESH_EXPIRATION Refresh token expiration (ms) 86400000

Profiles

  • dev: H2 in-memory database, debug logging, sample data
  • staging: PostgreSQL, info logging, Flyway migrations
  • prod: PostgreSQL, optimized settings, minimal logging

Testing

Run All Tests

# Unix/Linux/macOS
./mvnw test

# Windows PowerShell / Command Prompt
.\mvnw test

Run with Coverage

# Unix/Linux/macOS
./mvnw verify

# Windows PowerShell / Command Prompt
.\mvnw verify

Coverage report will be available at target/site/jacoco/index.html

Coverage Requirements

The project enforces a minimum 80% line coverage requirement via JaCoCo. The build will fail if coverage drops below this threshold.

Current test coverage includes:

Layer Classes Tested
Application Services BookService, CheckoutService, AuthService, UserService
Mappers BookMapper, CheckoutMapper
Controllers BookController, CheckoutController, AuthController
Security JwtTokenProvider, JwtAuthenticationFilter
Filters RequestTracingFilter
Domain Models Book, User, Checkout

Test Structure

src/test/java/com/library/
├── application/
│   ├── mapper/           # Mapper unit tests
│   └── service/          # Service unit tests
├── domain/
│   └── model/            # Domain model tests
├── infrastructure/
│   └── security/         # Security component tests
└── presentation/
    ├── controller/       # Controller tests (MockMvc)
    └── filter/           # Filter unit tests

Business Rules

  1. Book Deletion/Update: Books with active checkouts cannot be deleted or updated
  2. Checkout Duration: Default checkout period is 14 days
  3. Return Ownership: Members can only return their own checkouts
  4. ISBN Uniqueness: Each book must have a unique ISBN
  5. Available Copies: Checkout decrements available copies; return increments

Error Responses

The API uses RFC 7807 Problem Detail format for errors:

{
    "type": "https://api.library.com/errors/not-found",
    "title": "Resource Not Found",
    "status": 404,
    "detail": "Book with ID abc123 not found",
    "timestamp": "2025-01-15T10:30:00Z",
    "resourceType": "Book",
    "identifier": "abc123"
}

License

This project is for demonstration purposes.

About

A Spring Boot 4 REST API for managing a library's book inventory and member checkout operations.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages