Skip to content

Latest commit

 

History

History
54 lines (39 loc) · 1.94 KB

File metadata and controls

54 lines (39 loc) · 1.94 KB

shelf-api-java

Java backend for Shelf, a tiny personal reading tracker. Owns auth and the User/Book domain; delegates cover/description lookup to shelf-enrichment-python.

Stack

Spring Boot 3.2 (Java 17), Spring Data JPA + H2 (file-based, no server to install), JJWT for auth tokens, spring-security-crypto for password hashing (no full Security starter — one hand-written filter is enough for this project).

Architecture

Controller (AuthController, BookController)
  -> Service (AuthService, BookService)
       -> Repository (UserRepository, BookRepository : JpaRepository)
       -> EnrichmentClient (interface) -> OpenLibraryEnrichmentClient (impl)
                                             -> HTTP call to shelf-enrichment-python

Book/User both extend BaseEntity. BookService.addBook saves the book first, then applies enrichment as a best-effort step — a failure there (enrichment service down, external API down) never loses the book itself.

Auth

POST /api/auth/login issues a JWT (HS256) signed with SHELF_JWT_SECRET. Every /api/books/** request must carry it as Authorization: Bearer <token>. shelf-enrichment-python validates the same token with the same secret — it never talks to this service to check a session.

Run locally

cp .env.example .env   # then `export $(cat .env | xargs)` or set the vars another way
mvn spring-boot:run

Runs on http://localhost:8080. The H2 database file is created under ./data/ on first run.

Test

mvn test

Endpoints

Method Path Auth Body Notes
POST /api/auth/signup {username, password} password min 6 chars
POST /api/auth/login {username, password} returns {token, tokenType}
GET /api/books Bearer books owned by the caller
POST /api/books Bearer {title, author} saves, then enriches best-effort