This project is a RESTful API built using Node.js, Express.js, MongoDB, Mongoose, and Multer.
It was created as part of my internship project at Syntecxhub. The project allows users to upload, update, view, and delete their profile picture. The uploaded image metadata is stored in MongoDB and associated with a user document.
- Create a new user
- Get all users
- Get a single user by ID
- Upload user profile picture
- Update user profile picture
- Delete user profile picture
- Store file metadata in MongoDB
- Associate uploaded image with user document
- Serve uploaded images using URL
- Validate image file type
- Restrict file size to 2MB
- Handle multipart/form-data using Multer
- Proper status codes and JSON responses
- Node.js
- Express.js
- MongoDB
- Mongoose
- Multer
- Dotenv
- CORS
- Postman
user-profile-image-upload-api
│
├── controllers
│ └── userController.js
│
├── models
│ └── User.js
│
├── routes
│ └── userRoutes.js
│
├── uploads
│
├── .env
├── server.js
├── package.json
└── README.mdClone the repository:
git clone https://github.com/your-username/user-profile-image-upload-api.gitGo to the project folder:
cd user-profile-image-upload-apiInstall dependencies:
npm installCreate a .env file in the root folder and add:
PORT=5000
MONGO_URI=mongodb://127.0.0.1:27017/profile_image_upload_api
BASE_URL=http://localhost:5000Run the project:
npm run devThe server will start on:
http://localhost:5000Each user contains basic details and profile picture metadata.
{
"name": "Vikas Kushwaha",
"email": "vikas@example.com",
"profilePicture": {
"filename": "profile-1715600000000-123456789.png",
"path": "uploads/profile-1715600000000-123456789.png",
"url": "http://localhost:5000/uploads/profile-1715600000000-123456789.png",
"mimetype": "image/png",
"size": 120000
}
}| Method | Endpoint | Description |
|---|---|---|
| POST | /api/users |
Create a new user |
| GET | /api/users |
Get all users |
| GET | /api/users/:id |
Get a single user by ID |
| POST | /api/users/:id/profile-picture |
Upload profile picture |
| PUT | /api/users/:id/profile-picture |
Update profile picture |
| DELETE | /api/users/:id/profile-picture |
Delete profile picture |
| GET | /uploads/:filename |
Serve uploaded image |
POST /api/usersRequest body:
{
"name": "Vikas Kushwaha",
"email": "vikas@example.com"
}Sample response:
{
"success": true,
"message": "User created successfully",
"data": {
"_id": "6644c8f23b9d9f8a12c12345",
"name": "Vikas Kushwaha",
"email": "vikas@example.com",
"profilePicture": null,
"createdAt": "2026-05-14T10:30:00.000Z",
"updatedAt": "2026-05-14T10:30:00.000Z"
}
}GET /api/usersSample response:
{
"success": true,
"message": "Users fetched successfully",
"totalUsers": 1,
"data": [
{
"_id": "6644c8f23b9d9f8a12c12345",
"name": "Vikas Kushwaha",
"email": "vikas@example.com",
"profilePicture": null
}
]
}GET /api/users/user_id_herePOST /api/users/user_id_here/profile-pictureIn Postman, use:
Body → form-data
Key: profilePicture
Type: File
Value: Select image file
Important: the file field name must be:
profilePicture
Sample response:
{
"success": true,
"message": "Profile picture uploaded successfully",
"data": {
"filename": "profile-1715600000000-123456789.png",
"path": "uploads/profile-1715600000000-123456789.png",
"url": "http://localhost:5000/uploads/profile-1715600000000-123456789.png",
"mimetype": "image/png",
"size": 120000
}
}PUT /api/users/user_id_here/profile-pictureIn Postman, use:
Body → form-data
Key: profilePicture
Type: File
Value: Select new image file
When a new profile picture is uploaded, the old image is deleted from the uploads folder and the new image metadata is saved in MongoDB.
DELETE /api/users/user_id_here/profile-pictureSample response:
{
"success": true,
"message": "Profile picture deleted successfully"
}After deleting, the image is removed from the uploads folder and the profilePicture field becomes null.
After uploading an image, the API returns an image URL.
Example:
http://localhost:5000/uploads/profile-1715600000000-123456789.pngOpen this URL in the browser to view the uploaded image.
Only image files are allowed.
Allowed file types:
jpg, jpeg, png, webp
Maximum file size:
2MB
If another file type is uploaded, the API returns an error.
Example:
{
"success": false,
"message": "Only image files are allowed: jpeg, jpg, png, webp"
}This project uses Multer to handle multipart/form-data.
The image must be uploaded using the key:
profilePicture
The API was tested using Postman.
Testing process:
- Create a user using the POST API
- Copy the user ID from the response
- Upload profile picture using the user ID
- Open the returned image URL in the browser
- Get the user by ID and check image metadata
- Update the profile picture with a new image
- Check that the old image is removed from the uploads folder
- Delete the profile picture
- Check that the image is removed and metadata becomes null
Create user:
POST /api/usersUpload image:
POST /api/users/6644c8f23b9d9f8a12c12345/profile-pictureView image:
GET /uploads/profile-1715600000000-123456789.pngUpdate image:
PUT /api/users/6644c8f23b9d9f8a12c12345/profile-pictureDelete image:
DELETE /api/users/6644c8f23b9d9f8a12c12345/profile-pictureUser not found:
{
"success": false,
"message": "User not found"
}No image uploaded:
{
"success": false,
"message": "Please upload an image file"
}No profile picture found:
{
"success": false,
"message": "User does not have a profile picture"
}Vikas Kushwaha