A RESTful API built using Node.js, Express.js, and MongoDB, allowing users to manage books and post reviews. Authenticated users can add books, post reviews, and manage their own content. This project demonstrates secure backend development, clean modular code, and well-designed API architecture.
- User Signup & Login (JWT-based authentication)
- Add and View Books with pagination, filtering, and search
- Post one review per book per user
- Update or delete your own reviews
- Search books by title or author (partial & case-insensitive)
- Modular project structure for scalability
- Backend: Node.js, Express.js
- Database: MongoDB (Mongoose)
- Authentication: JWT (JSON Web Tokens)
- Environment Config: dotenv
- Pagination & Filtering: Built-in query options
bookstacker/
│
├── controllers/ # Route controllers (logic)
├── services/ # Business logic
├── models/ # Mongoose schemas
├── routes/ # Route definitions
├── middleware/ # JWT auth, error handlers
├── config/ # DB and env config
├── .env # Secret keys & config
├── server.js # App entry point
└── README.md
- Clone the repo
git clone https://github.com/sunnysagar/BookStacker.git cd BookStacker
- Install dependencies
npm install
- Create a .env file
PORT=5000 MONGO_URI=your_mongodb_uri JWT_SECRET=your_jwt_secret_key
- Start Server
node server.js
Your API will be running at
http://localhost:5000
POST /api/auth/signup
POST /api/auth/login
POST /api/books (auth)
GET /api/books
GET /api/books/:id
POST /api/books/:id/reviews (auth)
PUT /api/reviews/:id (auth)
DELETE /api/reviews/:id (auth)
GET /api/books/search?q=title
- Signup – Register
POST /auth/signup Content-Type: application/json { "name": "Sunny", "email": "[email protected]", "password": "securepassword" }
- Login and Get JWT
POST /auth/login { "email": "[email protected]", "password": "securepassword" }
- POST /books – Add Book (Auth Required)
POST /books Authorization: Bearer <JWT> { "title": "Clean Code", "author": "Robert C. Martin", "genre": "Programming" }
- GET /books – List Books (pagination, filter)
GET /books?page=1&limit=10&author=Robert&genre=Programming
- GET /books/:id – Book Details with Avg Rating + Reviews
GET /books/abc123
- POST /books/:id/reviews (One review per user per book)
POST /books/abc123/reviews Authorization: Bearer <JWT> { "rating": 4, "comment": "Great book!" }
- PUT /reviews/:id – Update Own Review
PUT /reviews/xyz456 Authorization: Bearer <JWT> { "rating": 5, "comment": "Actually, it was amazing!" }
- DELETE /reviews/:id – Delete Own Review
DELETE /reviews/xyz456 Authorization: Bearer <JWT>
GET /search?q=clean
- User
{
name: String,
email: { type: String, unique: true },
password: String
}
- Book
{
title: String,
author: String,
genre: String,
reviews: [ObjectId], // References to Review
}
- Review
{
user: ObjectId,
book: ObjectId,
rating: Number,
comment: String
}
📌 Key Entities:
- User: Stores user credentials and basic details.
- Book: Contains book information like title, author, and genre.
- Review: Connects a user and a book through a one-to-one relationship per book, with a rating and comment.
Field | Type | Description |
---|---|---|
_id |
ObjectId | Primary key |
name |
String | User’s full name |
email |
String | Unique email |
password |
String | Hashed password |
Field | Type | Description |
---|---|---|
_id |
ObjectId | Primary key |
title |
String | Title of the book |
author |
String | Author's name |
genre |
String | Book genre |
Field | Type | Description |
---|---|---|
_id |
ObjectId | Primary key |
user |
ObjectId | Reference to the User (_id ) |
book |
ObjectId | Reference to the Book (_id ) |
rating |
Number | Rating (e.g., 1 to 5) |
comment |
String | Review comment |
The following diagram represents the core entities and their relationships in the Book Review API system.
📎 ER Diagram Link:
📄 View ER Diagram on Google Drive
- A User can write many Reviews, but only one review per Book.
- A Book can have many Reviews.
- Each Review belongs to one User and one Book.
- Modular Structure: Separated controllers (handle requests) and services (handle logic) for cleaner code.
- JWT Authentication: Protected routes require JWT in the Authorization header.
- One Review per Book per User: Enforced to maintain review uniqueness.
- Pagination: Default limit = 10 in book and review listings.
- Search: Case-insensitive partial match for title and author using regex.
- Protected Routes: Only logged-in users can add books or reviews.
- All users are treated equally (no roles like admin).
- Users can update or delete only their own reviews.
- Basic validation is handled via Mongoose.
- No advanced features like likes, replies, or media for now.