Building a Node.js Express REST API with MongoDB
In this guide, we’ll create a Node.js Express REST API that allows users to register, log in, and upload their profile images. We’ll use MongoDB for storing user data and Multer for handling file uploads. The API will provide endpoints for registering a new user, logging in, and retrieving user details.
Prerequisites
Before we start coding, make sure you have the following:
- Node.js installed: You can download and install Node.js from here.
- MongoDB installed locally or use a cloud service like MongoDB Atlas.
- Postman or any API testing tool to test your API.
Step 1: Project Setup
Let’s start by creating the project folder and installing the necessary dependencies.
1.1 Create Project Folder
mkdir user-api
cd user-api
1.2 Initialize the Node.js Project
Run the following command to initialize your project with default values:
npm init -y
1.3 Install Dependencies
Next, let’s install the required dependencies:
npm install express mongoose multer bcryptjs dotenv
express: A web framework for Node.js.
mongoose: A MongoDB object modeling tool.
multer: Middleware for handling file uploads.
bcryptjs: For hashing passwords securely.
dotenv: For managing environment variables.
Step 2: Environment Setup
To store sensitive information like database connection strings and secret keys, create a .env file in the root of your project.
2.1 Create .env File
touch .env
Inside the .env file, add the following:
MONGO_URI=mongodb://localhost:27017/userdb
JWT_SECRET=your_secret_key
Replace your_secret_key with a secure key for JWT or just for general use if you are not using JWT for authentication.
Step 3: Define the User Model
The User model will define the structure of the user data in MongoDB, such as the name, email, password, and profile image.
3.1 Create 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, // This will store the file name or path of the uploaded image
required: false,
},
},
{ timestamps: true }
);
module.exports = mongoose.model("User", userSchema);
In the above schema:
- first_name, last_name, email, and password are required fields.
- image is an optional field that stores the path to the profile image.
Step 4: Setup Multer for File Uploads
We will use Multer for handling file uploads, specifically the user’s profile image. Multer stores files in a directory, and we will define the destination and filename format.
4.1 Setup Multer
Create a folder called uploads where the profile images will be stored.
mkdir uploads
4.2 Create File Upload Logic
In the routes/user.js file, we’ll set up Multer and add routes for registering users and uploading images.
const express = require("express");
const bcrypt = require("bcryptjs");
const multer = require("multer");
const path = require("path");
const User = require("../models/User");
const router = express.Router();
// Configure multer storage and filename
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "uploads/"); // Specify the upload directory
},
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname)); // Create a unique filename
},
});
const upload = multer({ storage: storage });
// Register user with image upload
router.post("/register", upload.single("image"), async (req, res) => {
try {
const { first_name, last_name, email, password } = req.body;
// Check if user already exists by email
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(400).json({ message: "Email already exists" });
}
// Hash the password before saving it
const hashedPassword = await bcrypt.hash(password, 10);
// Create the user document
const newUser = new User({
first_name,
last_name,
email,
password: hashedPassword,
image: req.file ? req.file.filename : null, // Store image filename if uploaded
});
// Save user to the database
await newUser.save();
res.status(201).json({ message: "User registered successfully", user: newUser });
} catch (err) {
console.error(err);
res.status(500).json({ message: "Server error" });
}
});
Step 5: Setup Express Server
The server.js file will initialize the Express app, configure middleware, and set up routes.
5.1 Create server.js
const express = require("express");
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const userRoutes = require("./routes/user");
dotenv.config();
const app = express();
// Middleware
app.use(express.json()); // To parse incoming JSON requests
app.use("/uploads", express.static("uploads")); // Serve uploaded files from the uploads directory
// Routes
app.use("/api/users", userRoutes);
// Connect to MongoDB
mongoose
.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log("MongoDB connected");
app.listen(5000, () => {
console.log("Server is running on port 5000");
});
})
.catch((err) => {
console.error("MongoDB connection error:", err);
});
Step 6: Running the Application
Now that everything is set up, you can start the server using:
node server.js
Conclusion
This tutorial demonstrated how to build a solid Node.js Express REST API with MongoDB for user registration, login, and image upload. We used Multer for handling file uploads, bcryptjs for password hashing, and MongoDB for storing user data. The code is simple and can be extended with additional features like JWT authentication, email validation, and more.
By following these steps, you should now have a fully functional user management system, and you can easily integrate it with a front-end application like Angular or React.
