Deploying a Node.js Express API on Vercel: Effortless CRUD Operations with MongoDB Atlas and Direct Frontend Integration
Setting up a local server often means running XAMPP or similar software to expose an IP address, which can be cumbersome and resource-intensive. But there’s a simpler solution: leveraging third-party platforms like Vercel. These platforms, offering both free and premium tiers, allow you to deploy your Node.js server effortlessly.
Imagine this: you can directly access your MongoDB collection, perform custom CRUD operations, and get a live server link, all without the hassle of configuring a local environment. With Vercel, you can deploy your server and instantly access it from anywhere, making your development process smoother and more efficient.
There are 3 main steps to create this.
1.MongoDB Atlas configuration
2.Node.js project setup with express app & mongodb setup
3.Deployment on Vercel
MongoDB Atlas configuration
Register on the platform MongoDB Atlas
Create data service and clustor
After that you will see the following portal structure,
Important Note: Due to security reasons Atlas does not allow requests from unknown ip which is not added into IP Access List, So in order to resolve that issue we need to allow access from any origin by adding the CIDR-notated 0.0.0.0/0
Node.js project setup with express app & mongodb setup
Create a folder and initiate the node project (npm i)
Now you would have node_modules and package.json ready
Get Hafeez Solutionriver’s stories in your inbox
Join Medium for free to get updates from this writer.
Add directory name API and add these file — index.js and mongo.db
const app = require('express')();
const cors = require('cors');
const express = require('express');
const { insert, getAll, deleteByName, updateByName } = require('./mongo-crud');
// Adding the cross-origin access
const corsOptions = {
origin: '*',
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type']
};
// Use CORS middleware with options
app.use(cors(corsOptions));
// Middleware to parse JSON
app.use(express.json());
// Root endpoint
app.get('/', (req, res) => {
res.send("Server is running....");
});
// Insert a new document
app.use(express.json());
app.post('/insert', async (req, res) => {
try {
const { name, price, quantity } = req.body;
await insert({ name, price, quantity });
res.status(200).send({ message: 'Document inserted successfully' });
} catch (err) {
console.error('Failed to insert document:', err);
if (!res.headersSent) {
res.status(500).send({ error: "Failed to insert the document" });
}
}
});
// Get all records
app.use(express.json());
app.get('/records', async (req, res) => {
try {
const records = await getAll();
res.status(200).send(records);
} catch (err) {
console.error('Failed to retrieve records:', err);
res.status(500).send({ error: "Failed to retrieve records" });
}
});
//To make it simple, I'm using the POST method for both delete and update
// Delete a record by name (using POST)
app.use(express.json());
app.post('/delete', async (req, res) => {
try {
const { name } = req.body;
await deleteByName(name);
res.status(200).send({ message: 'Document deleted successfully' });
} catch (err) {
console.error('Failed to delete document:', err);
res.status(500).send({ error: "Failed to delete the document" });
}
});
// Update a record by name (using POST)
app.use(express.json());
app.post('/update', async (req, res) => {
try {
const { name, newData } = req.body;
await updateByName(name, newData);
res.status(200).send({ message: 'Document updated successfully' });
} catch (err) {
console.error('Failed to update document:', err);
res.status(500).send({ error: "Failed to update the document" });
}
});
// // Start the server
// app.listen(3000, () => {
// console.log("Server is running on localhost:3000");
// });
module.exports = app;And mongo-crud.js
const { MongoClient, ServerApiVersion } = require('mongodb');
let client;
// For the security purpose, URI is placed in the env file
// Mongo Atlas would provide the URI when creating the database over there.
async function connectToDatabase() {
if (!client) {
client = new MongoClient(process.env.URI, {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true,
}
});
await client.connect();
console.log("Connected to MongoDB!");
}
return client;
}
async function insert(document) {
try {
const client = await connectToDatabase();
const database = client.db('APIS-Testing');
const collection = database.collection('Product');
const result = await collection.insertOne(document);
console.log(`Inserted document with id: ${result.insertedId}`);
} catch (err) {
console.error('Failed to insert document:', err);
}
}
async function getAll() {
try {
const client = await connectToDatabase();
const database = client.db('APIS-Testing');
const collection = database.collection('Product');
const documents = await collection.find({}).toArray();
console.log('Fetched all documents:', documents);
return documents;
} catch (err) {
console.error('Failed to retrieve documents:', err);
}
}
async function deleteByName(name) {
console.log('delete',name)
try {
const client = await connectToDatabase();
const database = client.db('APIS-Testing');
const collection = database.collection('Product');
const result = await collection.deleteOne({ name: name });
if (result.deletedCount > 0) {
console.log(`Deleted document with name: ${name}`);
} else {
console.log(`No document found with name: ${name}`);
}
} catch (err) {
console.error('Failed to delete document:', err);
}
}
async function updateByName(name, updateData) {
try {
const client = await connectToDatabase();
const database = client.db('APIS-Testing');
const collection = database.collection('Product');
const result = await collection.updateOne({ name: name }, { $set: updateData });
if (result.matchedCount > 0) {
console.log(`Updated document with name: ${name}`);
} else {
console.log(`No document found with name: ${name}`);
}
} catch (err) {
console.error('Failed to update document:', err);
}
}
// Closing the client connection when your app is shutting down
process.on('SIGINT', async () => {
if (client) {
await client.close();
console.log("MongoDB connection closed.");
process.exit(0);
}
});
// Exporting the CRUD methods to be used elsewhere
module.exports = {
insert,
getAll,
deleteByName,
updateByName
};Let me give the complete idea now!
index file contains the express apis endpoints which are using the methods provided by the mongo-crud option. For time being, I have created a collection of Product(name, price, quantity) —
P.S : You can change this according to your own requirements.
In addition, I have added the vercel.json file to override the default configuration of Vercel.
{
"rewrites": [
{ "source": "/(.*)", "destination": "/api" }
]
}The configuration in versel.json indicates that all incoming requests, regardless of the path, will be redirected to the /api endpoint. It effectively routes every request to be handled by the API.
Deployment on Vercel
Here comes the most easiest setup. Just push your code to your Github repo and sign in into Vercel and add a new deployment. Put your repo and do not forget to include your env variables if you have not exposed them in git repo.
Important Note: Vercel does not provide the dedicated ip address so that we can put that into MongoDB Atlas Network access — Therefore we need to either upgrade the vercel to have dedicated ip address or to allow the Atlas to receive the request from all origins using CIDR-Noted 0.0.0.0/0. We followed the later one which is completely free method!
Then wait for few seconds then boom boom boom!
If you are seeing this where server is running means it is completely working and you can test the endpoints.
Now you’re good to go, whether to use to directly in your frontend application by just invoking the endpoints.
For complete code visit my github repo. You can use it by customize it according to your own requirements.
If you encounter any issue then contact me on LinkedIn.
Best of Luck,




