NodeJs

Node.js Express API with Image Upload using MongoDB & Multe

📦 Node.js + Express + MongoDB API with Image Upload

Creating a backend API with image upload functionality is a common requirement in modern web applications. In this tutorial, you’ll learn how to build a powerful Node.js API using Express and connect it to a MongoDB database for storing user data. We’ll also use Multer to handle image uploads efficiently and securely. From setting up the project structure to creating routes and models, every step is explained clearly. By the end of this guide, you’ll have a working backend capable of receiving form data and image files — perfect for user profile systems, CMS platforms, or any file-based application.

✅ Tech Stack

  • Express
  • Mongoose
  • Multer
  • dotenv
  • CORS

📁 Directory Structure


project/
├── uploads/
├── models/
│   └── User.js
├── routes/
│   └── userRoutes.js
├── app.js
├── .env
└── package.json
  

🔧 Step-by-Step Guide

1. Initialize Project & Install Dependencies


npm init -y
npm install express mongoose multer dotenv cors
  

2. .env File


PORT=5000
MONGO_URI=mongodb://127.0.0.1:27017/userdb
  

3. Create User Model – models/User.js


const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  first_name: { type: String, required: true },
  last_name:  { type: String, required: true },
  email:      { type: String, required: true, unique: true },
  password:   { type: String, required: true },
  image:      { type: String }
}, {
  timestamps: true
});

module.exports = mongoose.model('User', userSchema);
  

4. Create Routes – routes/userRoutes.js


const express = require('express');
const router = express.Router();
const User = require('../models/User');
const multer = require('multer');
const path = require('path');

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/');
  },
  filename: function (req, file, cb) {
    const uniqueName = `${Date.now()}-${file.originalname}`;
    cb(null, uniqueName);
  }
});
const upload = multer({ storage: storage });

router.post('/', upload.single('image'), async (req, res) => {
  try {
    const { first_name, last_name, email, password } = req.body;
    const image = req.file ? req.file.filename : null;

    const newUser = new User({ first_name, last_name, email, password, image });
    await newUser.save();
    res.status(201).json({ message: 'User created successfully', user: newUser });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

router.get('/', async (req, res) => {
  try {
    const users = await User.find();
    res.json(users);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

module.exports = router;
  

5. Main App Setup – app.js


const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const dotenv = require('dotenv');
const userRoutes = require('./routes/userRoutes');
const path = require('path');

dotenv.config();
const app = express();

app.use(cors());
app.use(express.json());
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

app.use('/api/users', userRoutes);

mongoose.connect(process.env.MONGO_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
})
.then(() => {
  console.log('MongoDB connected');
  app.listen(process.env.PORT, () => console.log(`Server running on port ${process.env.PORT}`));
})
.catch(err => console.error(err));
  

6. Create uploads/ Directory


mkdir uploads
  

🧪 Test Using Postman

  • Method: POST
  • URL: /api/users
  • Form-data fields:
    • first_name: John
    • last_name: Doe
    • email: john@example.com
    • password: 123456
    • image: Choose file

🎯 Result

You will receive a JSON response confirming user creation and the uploaded image’s filename will be stored in the database.

✨ Optional

  • Add JWT Authentication
  • Create a React frontend to upload and view users
  • Validate inputs using express-validator

Leave a Reply

Your email address will not be published. Required fields are marked *