Creating Powerful REST APIs: A Step-by-Step Guide to Building and Integrating with Databases using Node.js
Table of contents
- Introduction
- Building RESTful API using Node.js
- Conclusion
Introduction
In today's interconnected digital landscape, building reliable and efficient REST APIs is a core skill for modern developers. Combining the power of a database with a RESTful architecture opens up a world of possibilities for data-driven applications. In this comprehensive guide, we'll walk you through the process of building a simple yet powerful REST API with seamless database integration. Whether you're a beginner or an experienced developer, follow along to learn how to harness the potential of APIs and databases to create impactful apps.
Building RESTful API using Node.js
In this tutorial, we will leverage Express.js, a powerful web application framework for Node.js. Express.js streamlines building, routing, and processing of requests, allowing developers to build server-side applications that are both efficient and easily scalable. Previous API development experience is not a necessary prerequisite. By following the steps outlined, you can build your own RESTful API in just half an hour.
Step 1: API Endpoints
Before diving into the code editor, you should familiarize yourself with the scope of the project and the structure of the API. Our focus includes implementing CRUD operations complemented by seamless database integration, with MongoDB serving as the database solution of choice. For greater clarity, let's establish a precise definition of the relevant endpoints.
HTTP Request | Endpoint name | Description |
GET | /users | Get the names of all users present in the database |
GET | /users/:email | Get a specific user for that email |
POST | /users | Add a new user to the database |
PUT | /users/:email | Update details of an already existing user using their email |
DELETE | /users/:email | Delete details of a user using their email |
Having outlined our API endpoints, you may have noticed a common denominator across all of them: the inclusion of /users
. You might be wondering whether this uniformity could lead to errors. However, it`s important to clarify that this won't pose an issue. The reason lies in the HTTP request methods – specifically, GET, POST, PUT, and DELETE – which inherently distinguish each request, rendering the endpoints uniquely identifiable and functional.
Step 2: Setting up the project
We need to create a folder that stores our application and set up Express.js in that folder. Open your system terminal and follow the steps :
Create a new directory for your project:
mkdir rest-api
Navigate into the project directory:
cd rest-api
Initialize new Node.js project:
npm init -y
Install Express.js, Mongoose, and DotEnv as dependencies:
npm i express mongoose dotenv bcrypt
Step 3: Create the server
Once the project has been initialized, we now need to create the server.
Create a file
index.js
in your project directoryOpen
index.js
and write the necessary code in it.
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const port = 3000;
require('dotenv').config();
mongoose.connect(process.env.DATABASE_URL)
.then(()=>{
app.listen(port,()=>{
console.log('Databse connected and server listening at port' + port);
})
})
.catch((e)=>{
console.log(e)
})
This will import required modules, set up environment variables, and set the port to 3000. This will also create a connection with the database and start the server to listen on port 3000.
Step 4: Set environment variables
Once the server has been created we need to add environment variables so that crucial information such as database connection string (database URL) is not exposed for unauthorized access. For that follow the steps:
Create
.env
file in your project directoryCopy the connection string for your database from MongoDB.
Add this line to your
.env
fileDATABASE_URL='your_connection_string
Replace
your_connection_string
with the one provided by MongoDB
Step 5: Define API Routes
Create a folder named
router
in your project directoryInside the folder create a file named
routes.js
Open the file and define your API routes.
const express = require('express');
const router = express.Router();
// Define your routes here
module.exports = router;
Step 6: Define the Model for the Database
Create a folder named
model
in your project directoryInside the folder create a file named
user.js
Open the file and define the database schema as well as create a model.
const mongoose = require("mongoose");
// User schema
module.exports = mongoose.model("User", userSchema);
Step 7: Implement User schema
Now, we need to create a User schema in the user.js
file so that our database is able to understand how the data is stored and accessed.
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
minlength: 6,
},
},
{ versionKey: false }
);
Step 8: Implement CRUD Operations
Once all the above steps are done, we will then implement CRUD operations so that data can be processed.
Import the model we have defined
Import the module
bcrypt
which will be later used to hash passwords.
const bcrypt = require("bcrypt");
const User = require("../model/User");
Now, we will add all our endpoints. Also, we'll make sure that all of them are async as fetching from the database can sometimes take time.
GET all users /users
router.get("/", async (req, res) => {
try {
const users = await User.find();
res.status(200).json({ users });
} catch (e) {
console.error(e);
res.status(500).json({ message: "Internal server error" });
}
});
GET users by email
router.get("/:email", async (req, res) => {
const userEmail = req.params.email;
try {
const user = await User.findOne({ email: userEmail });
if (!user) {
return res.status(404).json({ message: "User not found" });
}
res.status(200).json(user);
} catch (e) {
console.error(e);
res.status(500).json({ message: "Internal server error" });
}
});
POST a new user
router.post("/", async (req, res) => {
const { name, email, password } = req.body;
try {
const existingUser = await User.findOne({ email });
if (existingUser) {
return res
.status(400)
.json({ message: "User Already Exists! Login Instead" });
}
const hashedPassword = await bcrypt.hash(password, 10);
const user = new User({ name, email, password: hashedPassword });
await user.save();
return res.status(201).json({ user });
} catch (e) {
console.error(e);
res.status(500).json({ message: "Internal Server Error" });
}
});
PUT Update user by email
router.put("/:email", async (req, res) => {
const userEmail = req.params.email;
const { name, email, password } = req.body;
try {
const user = await User.findOneAndUpdate(
{ email: userEmail },
{ name, email, password },
{ new: true }
);
if (!user) {
return res.status(404).json({ message: "User not found" });
}
return res.status(200).json(user);
} catch (e) {
console.error(e);
return res.status(500).json({ message: "Internal Server Error" });
}
});
DELETE user by email
router.delete("/:email", async (req, res) => {
const userEmail = req.params.email;
try {
const user = await User.findOneAndDelete({ email: userEmail });
if (!user) {
return res.status(404).json({ message: "User not found" });
}
return res.status(200).json({ message: "User deleted successfully", user });
} catch (e) {
console.error(e);
return res.status(500).json({ message: "Internal Server Error" });
}
});
STEP 9: Add route to the server
Though almost everything is complete, our API will still not work because we haven't connected routes to our server. This code shows how we can connect routes to the server.
const apiRouter = require("./router/routes");
app.use(express.json());
app.use("/users", apiRouter);
app.get("/", (req, res) => {
res.send("root directory. Server running.");
});
We have an app.get
so that out /
routes show something instead of throwing an error.
STEP 10: Final Code
You can find the final code in Rest API Tutorial Github Repository
And to run the code simply use node index.js
in your terminal.
Also, you can access the deployed API here
Conclusion
By the end of this tutorial, you'll have a solid understanding of how to build a simple REST API with database integration. Armed with this knowledge, you'll be well-equipped to expand your skills and develop more complex applications that harness the full potential of APIs and databases. Whether you're building a personal project, a startup, or an enterprise-grade application, the principles and techniques covered in this guide will serve as a solid foundation for your API development journey. your. Get ready to turn ideas into reality and connect the digital world with the power of APIs and databases.