A modular Bookstore REST API built with Node.js, Express, and MongoDB, featuring JWT authentication, CRUD operations for books and authors, and MVC architecture.
- 📖 CRUD for books and authors
- 👤 User authentication & authorization with JWT
- ✅ Request validation with ajv
- 🛡 Secure setup with Helmet, CORS, rate limiting, bcrypt password hashing
- 📝 Centralized error handling & logging middleware (winston)
- 📦 Seed script for sample data
- 🧪 Unit & integration testing with Jest + Supertest
- 📜 OpenAPI/Swagger documentation (
docs/swagger.json
)
bookstore-backend/
├─ src/
│ ├─ server.js # server entry
│ ├─ app.js # express app setup
│ ├─ config/ # env, db, jwt helpers
│ ├─ models/ # mongoose schemas
│ ├─ controllers/ # request/response handling
│ ├─ services/ # business logic
│ ├─ routes/ # api endpoints
│ ├─ middlewares/ # auth, error, logger, validation
│ ├─ validators/ # request validation
│ ├─ utils/ # shared helpers
│ ├─ scripts/ # seed & setup scripts
│ ├─ tests/ # jest + supertest tests
│ ├─ public/ & views/ # optional: static files + ejs templates
├─ docs/ # swagger/openapi docs
├─ .env.example # environment variables
├─ docker-compose.yml # optional: mongo + server
└─ Dockerfile # docker build
git clone https://github.com/your-username/bookstore-backend.git
cd bookstore-backend
npm install
Create a .env
file based on .env.example
:
PORT=3000
MONGO_URI=mongodb://localhost:27017/bookstore
JWT_SECRET=replace_this_with_a_strong_secret
JWT_EXPIRES_IN=1d
NODE_ENV=development
# Development (with nodemon)
npm run dev
# Production
npm start
Run tests with Jest + Supertest:
npm test
Populate MongoDB with sample data:
npm run seed
The API is documented with Swagger.
- JSON spec:
docs/swagger.json
- You can integrate Swagger UI to view docs in the browser.
The project includes:
Dockerfile
for containerizationdocker-compose.yml
for local MongoDB setup- CI workflow example in
.github/workflows/ci.yml
Can be deployed to Render, Railway, Fly.io, DigitalOcean, or Heroku.
Pull requests are welcome! For major changes, please open an issue first to discuss what you’d like to change.