Node.js, Express.js, Mongoose.js, and MongoDB are great combinations for building easy and fast REST API. You will see how fast that combination is than other existing frameworks because Node.js is a packaged compilation of Google’s V8 JavaScript engine and it works on non-blocking and event-driven I/O. Express.js is a Javascript web server that has the complete function of web development including REST API.
This tutorial is divided into several steps:
- Step #1: Create Express.js Project and Install Required Modules
- Step #2: Add Mongoose.js Module as ORM for MongoDB
- Step #3: Create Product Mongoose Model
- Step #4: Create Routes for the REST API endpoint
- Step #5: Test REST API Endpoints
In this tutorial, we will create a Node REST API of Product data. The Product is accessible through the Express REST API with the method of GET, POST, PUT, and DELETE. The Express route from the request of REST API to the Mongoose query points to the Mongoose model and persists in the MongoDB database.
Before we begin, make sure you have installed all the tools that are required.
- Node.js
- Express.js
- MongoDB
- Mongoose.js
- Text Editor or IDE (we are using VSCode)
You can watch the video tutorial on our YouTube channel.
In this tutorial, we will work using Terminal and Atom as the text editor. For Windows users, you can work using the Node.js command line. We started this Node.js, Express.js, Mongoose.js, and MongoDB tutorial from scratch.
Step #1: Create Express.js Project and Install Required Modules
Before jumping to the main step, make sure you have downloaded the latest Node.js and NPM. Type these commands to check if everything is up to date.
node -v
v18.14.0
npm -v
9.5.1
Next, install express-generator using this command.
npm install express-generator -g
Next, create an Express.js app using this command.
express --view=ejs node-mongodb-restapi
This will create the Express.js project with the EJS view instead of the Jade view template because using the '-e' parameter. Next, go to the newly created project folder then install node modules.
cd node-mongodb-restapi
npm install
Run the server by this command.
npm start
You will see the log like this in the terminal.
> [email protected] start
> node ./bin/www
Open your browser then point to 'localhost:3000', if you see the image below then your server is ready.
Step #2: Add Mongoose.js Module as ORM for MongoDB
Why use Mongoose MongoDB ODM? Because Mongoose provides a straightforward, schema-based solution to model your application data. It includes built-in type casting, validation, query building, business logic hooks, and more, out-of-the-box. Next, stop the node by pushing CTRL+C on the keyboard. Type this command to install the Mongoose.js module.
npm install mongoose --save
Before running your server again, make sure the MongoDB server is running. Open another terminal, then type this command to start the MongoDB server.
mongod
Now, open and edit app.js in the root of the project folder using your favorite text editor or IDE. Declare mongoose in required sections.
const mongoose = require('mongoose');
Use mongoose with native Node Promise.
mongoose.Promise = global.Promise;
Create a connection to MongoDB.
mongoose.connect('mongodb://nodeUser:Q1w2e3r4@localhost:27017/product', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('connection succesful'))
.catch((err) => console.error(err));
Next, run the node app again.
npm start
You should see this message on the terminal. It means the connection to MongoDB is successful.
> [email protected] start
> node ./bin/www
connection succesful
Step #3: Create Product Mongoose Model
Now, create a models directory and javascript file as the model. Before doing that, stop the Node server by pushing the CTRL+C key in the terminal.
mkdir models
touch models/Product.js
Open and edit the Product.js file then add these lines of code.
const mongoose = require('mongoose');
const ProductSchema = new mongoose.Schema({
prod_name: String,
prod_desc: String,
prod_price: Number,
updated_at: { type: Date, default: Date.now },
});
module.exports = mongoose.model('Product', ProductSchema);
That Schema will map to MongoDB collections called products. If you want to know more about Mongoose Schema Datatypes you can find it here.
Step #4: Create Routes for the REST API endpoint
The REST API that we build will have the following functions.
Method Endpoints Notes
GET /product Get all products
GET /product/:id Get single product
POST /product Add product
PUT /product/:id Update product
DELETE /product/:id Delete product
To achieve that, add the javascript file to the routes folder.
touch routes/products.js
Open and edit routes/products.js then add these lines of codes.
const express = require('express');
const router = express.Router();
const Product = require('../models/Product.js');
/* GET ALL PRODUCTS */
router.get('/', async function (req, res, next) {
try {
const products = await Product.find();
res.json(products);
} catch (error) {
return next(error);
}
});
/* GET SINGLE PRODUCT BY ID */
router.get('/:id', async function (req, res, next) {
try {
const product = await Product.findById(req.params.id);
res.json(product);
} catch (error) {
return next(error);
}
});
/* SAVE PRODUCT */
router.post('/', function (req, res, next) {
try {
const newProduct = new Product(req.body);
newProduct.save().then((prod) => res.json(prod));
} catch (error) {
return next(error);
}
});
/* UPDATE PRODUCT */
router.put('/:id', async function (req, res, next) {
try {
const product = await Product.findByIdAndUpdate(req.params.id, req.body);
res.json(product);
} catch (error) {
return next(error);
}
});
/* DELETE PRODUCT */
router.delete('/:id', async function (req, res, next) {
try {
const product = await Product.findByIdAndDelete(req.params.id);
res.json(product);
} catch (error) {
return next(error);
}
});
module.exports = router;
Next, open and edit app.js then add product route as required after users require.
const products = require('./routes/products');
Then add use after use of users.
app.use('/api/v1/products', products);
Step #5: Test REST API Endpoints
Before testing the Node server, we need to add a user to the database that we will use. Run the mongosh command in the cmd or terminal, after the MongoDB server running.
mongosh
Enter the database that we will use.
use product
Add a user to that database then exit the MongoDB shell.
db.createUser({user:"nodeUser", pwd: passwordPrompt(), roles: [{role:"readWrite", db:"produc
t"}]});
After everything is ready, this time test our created Node.js, Express.js, Mongoose.js, and MongoDB REST API. There are so many tools for testing REST API, but for now, we are testing using CURL from the terminal. First, run again this Node.js-Express-MongoDB server.
npm start
We start with Adding/Saving product data first. Open a new terminal tab or windows then type this command.
curl -i -X POST -H "Content-Type: application/json" -d '{ "prod_name":"XBox One","prod_desc":"New Microsoft XBox One, the latest games console","prod_price": 520 }' localhost:3000/products
If you get a response like below, then you save a new product successfully.
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 185
ETag: W/"b9-RaOpfmQ2pg692WTnIhsUGBf8xvc"
Date: Sat, 11 Mar 2023 00:28:46 GMT
Connection: keep-alive
Keep-Alive: timeout=5
{"prod_name":"XBox One","prod_desc":"New Microsoft XBox One, the latest games console","prod_price":520,"_id":"640bcb3e0a4c058c135b7596","updated_at":"2023-03-11T00:28:46.862Z","__v":0}
We can create the same POST with different data to populate more records for product collection.
curl -i -X POST -H "Content-Type: application/json" -d '{ "prod_name":"Sony PS 4","prod_desc":"Sony playstation 4","prod_price": 580 }' localhost:3000/products
Next, we are testing to get all product data using this command.
curl -i -H "Accept: application/json" localhost:3000/products
That command will respond to product data in JSON format.
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 530
ETag: W/"212-htAQtQkGAlfXBDYyuaEIPnQmmxs"
Date: Sat, 11 Mar 2023 00:35:21 GMT
Connection: keep-alive
Keep-Alive: timeout=5
[{"_id":"640bc712f0fcc728ead7110a","prod_name":"XBox One","prod_desc":"New Microsoft XBox One, the latest games console","prod_price":520,"updated_at":"2023-03-11T00:10:58.208Z","__v":0},{"_id":"640bcb3e0a4c058c135b7596","prod_name":"XBox One","prod_desc":"New Microsoft XBox One, the latest games console","prod_price":520,"updated_at":"2023-03-11T00:28:46.862Z","__v":0},{"_id":"640bcbb10a4c058c135b7598","prod_name":"Sony PS 4","prod_desc":"Sony playstation 4","prod_price":580,"updated_at":"2023-03-11T00:30:41.447Z","__v":0}]
Next, we are testing to get one product by id using this command.
curl -i -H "Accept: application/json" localhost:3000/products/640bcb3e0a4c058c135b7596
The response should be like this.
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 185
ETag: W/"b9-1ki4Q21pEwyjD59jaAlfXs6A3nQ"
Date: Sat, 11 Mar 2023 00:36:08 GMT
Connection: keep-alive
Keep-Alive: timeout=5
{"_id":"640bcb3e0a4c058c135b7596","prod_name":"XBox One","prod_desc":"New Microsoft XBox One, the latest games console","prod_price":520,"updated_at":"2023-03-11T00:28:46.862Z","__v":0}
Next, we are editing and update one of a product by id using this command. First, copy the id from one of the products from the response before then paste it as the parameter.
curl -i -X PUT -H "Content-Type: application/json" -d '{"prod_desc":"Microsoft XBox One"}' localhost:3000/products/640bcb3e0a4c058c135b7596
It should respond like this.
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 185
ETag: W/"b9-1ki4Q21pEwyjD59jaAlfXs6A3nQ"
Date: Sat, 11 Mar 2023 00:41:03 GMT
Connection: keep-alive
Keep-Alive: timeout=5
{"_id":"640bcb3e0a4c058c135b7596","prod_name":"XBox One","prod_desc":"New Microsoft XBox One, the latest games console","prod_price":520,"updated_at":"2023-03-11T00:28:46.862Z","__v":0}
Finally, we are testing to delete one product by id using this command.
curl -i -X DELETE localhost:3000/products/640bcb3e0a4c058c135b7596
It will respond like this and the product with that id will be removed from the product collection.
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 155
ETag: W/"9b-MGK0FJAbzaPf69xRV0IdqScavD0"
Date: Sat, 11 Mar 2023 00:42:01 GMT
Connection: keep-alive
Keep-Alive: timeout=5
{"_id":"640bcb3e0a4c058c135b7596","prod_name":"XBox One","prod_desc":"Microsoft XBox One","prod_price":520,"updated_at":"2023-03-11T00:28:46.862Z","__v":0}
That is the Node.js Express.js Mongoose.js MongoDB Easy Build REST API. You can get the full source code from our GitHub.
That is just the basic. If you need more deep learning about Javascript, Node.js, Express.js, MongoDB, or related you can take the following cheap course
- Node.js Express Api Rest Formation Complte
- Building APIs doing Outside-In TDD in Node and Typescript
- Node JS
- JavaScript and Node.js Essentials for Test Automation
- Express.js Node.js & MongoDB
- Build Role-based Authentication using Node.js, JWT, Mongoose
Thanks!