A blog API built with Node.js, Express, and Prisma. It supports JWT authentication, image upload (Multer + Cloudinary), data validation (Joi), and provides endpoints for users, posts, and comments.
- Stack
- Installation
- Environment Variables
- Project Structure
- Routes
- Error Handling & Middleware
- Contributing
- License
- Node.js 18+
- Express 5
- Prisma (ORM)
- PostgreSQL (or other Prisma-supported DB)
- JWT for authentication
- Multer + Cloudinary for file uploads
- Joi for input validation
- bcrypt/bcryptjs for password hashing
git clone <REPO_URL>
cd blog-api
npm install
npm run devBy default the server runs at http://localhost:3000.
Create a .env file in the root directory:
PORT=3000
DATABASE_URL="postgresql://user:password@localhost:5432/blog_api"
JWT_SECRET="your_secret_key"
JWT_EXPIRES_IN="1d"
CLOUDINARY_CLOUD_NAME=xxx
CLOUDINARY_API_KEY=xxx
CLOUDINARY_API_SECRET=xxx
UPLOAD_DIR=./uploadssrc/
config/
cloudinary.js
joiSchemas.js
jwt.js
multer.js
prisma.js
middlewares/
authMiddleware.js
errorHandler.js
isAdmin.js
validateAndSanitize.js
modules/
auth/
authController.js
authRoutes.js
comments/
commentsControllers.js
commentsRoutes.js
posts/
postControllers.js
postRoutes.js
users/
userControllers.js
userRoutes.js
utils/
server.js
Base: /auth
POST /auth/register→ register a new user (with optional avatar)
Body:username, email, password, avatarImage (file)
Middlewares:upload.single("avatarImage"),validateAndSanitize(registerSchema)POST /auth/login→ user login
Body:email, password
Middlewares:validateAndSanitize(loginSchema)
Base: /users
GET /users/all→ list all users (admin only)
Middlewares:authMiddleware,isAdminGET /users/me→ get current authenticated user
Middlewares:authMiddlewarePUT /users/change-password→ change user password
Body:{ oldPassword, newPassword }
Middlewares:authMiddleware,validateAndSanitize(updatePasswordSchema)PUT /users/edit/:id→ edit user profile (with optional avatar)
Body:name?, email?, avatarImage? (file)
Middlewares:authMiddleware,upload.single("avatarImage"),validateAndSanitize(updateProfileSchema)DELETE /users/delete→ delete current user
Middlewares:authMiddlewareGET /users/search?query=<text>→ search usersGET /users/:id→ get a user's public profile
Base: /posts
POST /posts/→ create a new post (with optional cover image)
Middlewares:authMiddleware,validateAndSanitize(createPostSchema),upload.single("coverImage")GET /posts/all→ list all posts (admin only)
Middlewares:authMiddleware,isAdminGET /posts/me→ list current user's posts
Middlewares:authMiddlewareGET /posts/published→ list all published posts (public)PUT /posts/:id→ edit a post (with optional cover image)
Middlewares:authMiddleware,upload.single("coverImage")DELETE /posts/:id→ delete a post
Middlewares:authMiddlewarePOST /posts/:id/like→ like a post
Middlewares:authMiddlewarePOST /posts/:id/save→ save a post
Middlewares:authMiddlewareGET /posts/search?query=<text>→ search postsGET /posts/:id/comments→ get all comments of a postGET /posts/:id→ get post by id
Base: /comments
POST /comments/→ create a new comment
Middlewares:authMiddlewareGET /comments/→ list all comments
Middlewares:authMiddlewareGET /comments/:id→ get comment by idGET /comments/author/:authorId→ get comments by authorPUT /comments/:id→ edit a comment
Middlewares:authMiddlewareDELETE /comments/:id→ delete a comment
Middlewares:authMiddlewarePOST /comments/:id/like→ like a comment
Middlewares:authMiddleware
errorHandler.jscatches and formats errors as JSON.- Unknown routes return
{ error: "Not Found" }. - Authentication handled by
authMiddleware(JWT). - Admin-only routes require
isAdmin. - Data validation via Joi in
validateAndSanitize.
- Fork the repository
- Create your feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -m 'feat: add my feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request