A full-fledged CRUD backend application built with Node.js, Express, and MongoDB (Mongoose) following clean OOP architecture principles.
The application follows a clean layered architecture:
controllers → services → repositories → models
Each layer is implemented using ES6 classes:
- Controllers: Handle HTTP requests and responses only
- Services: Contain business logic only
- Repositories: Contain database logic only
- Models: Define data schemas using Mongoose
workshop-sesd/
├── src/
│ ├── config/
│ │ ├── database.js # MongoDB connection
│ │ └── jwt.js # JWT configuration
│ ├── models/
│ │ ├── Book.js
│ │ ├── Author.js
│ │ ├── Member.js
│ │ └── Borrowing.js
│ ├── repositories/
│ │ ├── BaseRepository.js
│ │ ├── BookRepository.js
│ │ ├── AuthorRepository.js
│ │ ├── MemberRepository.js
│ │ └── BorrowingRepository.js
│ ├── services/
│ │ ├── BookService.js
│ │ ├── AuthorService.js
│ │ ├── MemberService.js
│ │ └── BorrowingService.js
│ ├── controllers/
│ │ ├── BookController.js
│ │ ├── AuthorController.js
│ │ ├── MemberController.js
│ │ └── BorrowingController.js
│ ├── routes/
│ │ ├── bookRoutes.js
│ │ ├── authorRoutes.js
│ │ ├── memberRoutes.js
│ │ └── borrowingRoutes.js
│ ├── middleware/
│ │ ├── errorHandler.js # Centralized error handling
│ │ ├── auth.js # JWT authentication & authorization
│ │ └── validator.js # Input validation
│ └── utils/
│ └── errors.js # Custom error class
├── app.js # Express app configuration
├── server.js # Server entry point
├── package.json
└── README.md
- ✅ Create entity
- ✅ Get entity by ID
- ✅ Get list of entities
- ✅ Update entity
- ✅ Delete entity
- ✅ Search: Case-insensitive text search across multiple fields
- ✅ Filtering: Filter by specific fields (genre, status, etc.)
- ✅ Sorting: Sort by any field (asc/desc)
- ✅ Pagination: Page and limit parameters
- ✅ Input Validation: Comprehensive validation using express-validator
- ✅ Centralized Error Handling: Custom error handling middleware
- ✅ JWT Authentication: Secure token-based authentication
- ✅ Role-based Authorization: Different access levels (member, librarian, admin)
- Title, ISBN, Author, Genre, Published Year
- Total copies and available copies tracking
- Description, Publisher, Language
- First name, Last name, Email
- Bio, Nationality, Date of birth
- Active status
- First name, Last name, Email, Password
- Phone, Address, Membership type
- Role (member, librarian, admin)
- Max borrow limit
- Book, Member, Borrow date, Due date
- Return date, Status (borrowed/returned/overdue)
- Fine amount calculation
- Automatic status updates
- Install dependencies:
npm install- Create a
.envfile in the root directory:
PORT=3000
MONGODB_URI=mongodb://localhost:27017/library_management
JWT_SECRET=your-super-secret-jwt-key-change-in-production
JWT_EXPIRES_IN=7d
NODE_ENV=development-
Make sure MongoDB is running on your system
-
Start the server:
npm startFor development with auto-reload:
npm run devGET /api/v1/books- Get all books (with search, filter, sort, pagination)GET /api/v1/books/available- Get available booksGET /api/v1/books/:id- Get book by IDPOST /api/v1/books- Create book (librarian/admin only)PATCH /api/v1/books/:id- Update book (librarian/admin only)DELETE /api/v1/books/:id- Delete book (admin only)
GET /api/v1/authors- Get all authorsGET /api/v1/authors/active- Get active authorsGET /api/v1/authors/:id- Get author by IDPOST /api/v1/authors- Create author (librarian/admin only)PATCH /api/v1/authors/:id- Update author (librarian/admin only)DELETE /api/v1/authors/:id- Delete author (admin only)
POST /api/v1/members/register- Register new memberPOST /api/v1/members/login- Login memberGET /api/v1/members- Get all members (librarian/admin only)GET /api/v1/members/active- Get active members (librarian/admin only)GET /api/v1/members/:id- Get member by ID (authenticated)PATCH /api/v1/members/:id- Update member (authenticated)DELETE /api/v1/members/:id- Delete member (admin only)
GET /api/v1/borrowings- Get all borrowings (librarian/admin only)GET /api/v1/borrowings/active- Get active borrowingsGET /api/v1/borrowings/overdue- Get overdue borrowingsGET /api/v1/borrowings/member/:memberId- Get borrowings by memberGET /api/v1/borrowings/book/:bookId- Get borrowings by bookGET /api/v1/borrowings/:id- Get borrowing by IDPOST /api/v1/borrowings- Create borrowing (librarian/admin only)PATCH /api/v1/borrowings/:id- Update borrowing (librarian/admin only)PATCH /api/v1/borrowings/:id/return- Return book (librarian/admin only)DELETE /api/v1/borrowings/:id- Delete borrowing (admin only)
?search=keyword- Search across relevant fields (case-insensitive)
?genre=Fiction- Filter by genre?status=borrowed- Filter by status?isActive=true- Filter by active status?author=<authorId>- Filter by author?member=<memberId>- Filter by member
?sort=title- Sort ascending by title?sort=-createdAt- Sort descending by creation date?sort=publishedYear,-title- Multiple sort fields
?page=1- Page number (default: 1)?limit=10- Items per page (default: 10, max: 100)
GET /api/v1/books?search=harry&genre=Fiction&sort=-publishedYear&page=1&limit=20
Most endpoints require authentication. Include the JWT token in the Authorization header:
Authorization: Bearer <your-jwt-token>
POST /api/v1/members/register
{
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"password": "password123"
}POST /api/v1/members/login
{
"email": "john@example.com",
"password": "password123"
}Response includes a JWT token:
{
"status": "success",
"data": {
"member": { ... },
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}The API uses centralized error handling with consistent error responses:
{
"status": "error",
"message": "Error message here"
}- Node.js - Runtime environment
- Express - Web framework
- MongoDB - Database
- Mongoose - ODM
- JWT - Authentication
- bcryptjs - Password hashing
- express-validator - Input validation
- dotenv - Environment variables
- ✅ Clean separation of concerns
- ✅ ES6 classes for all layers
- ✅ Async/await throughout
- ✅ Comprehensive error handling
- ✅ Input validation
- ✅ Security best practices (password hashing, JWT)
- ✅ Database indexing for performance
- ✅ Virtual fields for computed properties
- ✅ Pre-save hooks for data transformation
ISC