Introduction
Hey there! Today I’m going to walk you through the process of creating a REST API with Express JS. REST APIs have become an essential part of modern web and mobile app development, and they allow us to build efficient and scalable backends for our applications.
Express JS is a powerful Node.js framework that makes building REST APIs easy and intuitive. In this article, I’ll guide you through the process of setting up your development environment, building your REST API, adding authentication, integrating with a database, testing your API, and deploying it to a production environment.
So, grab a cup of coffee, sit back, and let’s get started.
Setting Up The Development Environment
Before we start building our REST API, we need to set up our development environment. First, we need to make sure to have Node.js and NPM installed on our computer. If you don’t have them already, you can download them from the official website.
Once you have installed Node.js and NPM, we can proceed to install the Express JS framework. We can do this by running the following command in our terminal:
npm install express
This will install the latest version of Express JS in your project directory. Now that we have installed Express JS, we can create a new project directory where we will build our REST API. We can create a new directory by running the following command:
mkdir my-rest-api
We can navigate to our new project directory by running the following command:
cd my-rest-api
Building The REST API
Now that we have set up our development environment, we can start building our REST API. In Express JS, we can create routes for our API by using the express.Router()
method. This method allows us to create a new instance of a router and define our routes on it.
Let’s create a new file called routes.js
in our project directory where we will define our routes:
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.json({ message: 'Hello World!' });
});
module.exports = router;
In this code snippet, we have imported the Express JS framework and created a new instance of a router. We have defined a GET route on the root /
path of our API, which returns a JSON object with a message property.
Now that we have defined our routes, we can use them in our main Express JS application. Let’s create a new file called app.js
in our project directory where we will define our main application:
const express = require('express');
const app = express();
const routes = require('./routes');
app.use('/', routes);
const port = 3000;
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});
In this code snippet, we have created a new instance of an Express JS application and imported our routes from routes.js
. We have used the app.use()
method to use our routes on the root path of our application. Finally, we have defined a port number on which our application will run.
Now we can run our application by running the following command in our terminal:
node app.js
This will start our server on http://localhost:3000
, and we can test our API by navigating to that URL in our web browser. We should see our “Hello World!” message displayed on the page.
Implementing Authentication
Now that we have built a basic REST API, let’s add some authentication to it. We have different options when it comes to implementing authentication in our Express JS application, but we’ll use JSON Web Tokens (JWT) in this tutorial.
JSON Web Tokens are a secure way to authenticate users in our API. They are particularly useful for building stateless backends that can scale easily and don’t rely on session data.
To use JWT in our Express JS application, we first need to install the jsonwebtoken
package. We can do this by running the following command in our terminal:
npm install jsonwebtoken
Once we have installed the package, we can use it to generate and verify JWT tokens. Let’s create a new file called auth.js
in our project directory where we will define our authentication logic:
const jwt = require('jsonwebtoken');
const secret = 'mysecretkey';
function generateToken(user) {
const payload = {
sub: user.id,
name: user.name,
email: user.email,
};
const token = jwt.sign(payload, secret, { expiresIn: '1h' });
return token;
}
function verifyToken(token) {
try {
const payload = jwt.verify(token, secret);
return payload;
} catch (error) {
return null;
}
}
module.exports = {
generateToken,
verifyToken,
};
In this code snippet, we have imported the jsonwebtoken
package and defined a secret key that will be used to sign our tokens. We have created two functions: generateToken()
and verifyToken()
.
The generateToken()
function takes a user object as an argument and generates a JWT token with the user’s data in the payload. The token is signed using our secret key and set to expire after one hour.
The verifyToken()
function takes a token as an argument and verifies its authenticity using our secret key. If the token is valid, it returns the payload data. If the token is invalid or expired, it returns null.
Now we can use our authentication logic in our API routes. Let’s modify our routes.js
file to add a new authentication route:
const express = require('express');
const router = express.Router();
const auth = require('./auth');
router.post('/login', (req, res) => {
const { email, password } = req.body;
// Authenticate user
const user = { id: 1, name: 'John Doe', email: '[email protected]' };
const token = auth.generateToken(user);
res.json({ user, token });
});
router.get('/profile', (req, res) => {
const token = req.headers.authorization.split(' ')[1];
const payload = auth.verifyToken(token);
if (!payload) {
res.status(401).json({ message: 'Unauthorized' });
} else {
res.json({ user: payload });
}
});
module.exports = router;
In this code snippet, we have added two new routes: /login
and /profile
. The /login
route takes a user’s email and password as parameters and generates a JWT token using our generateToken()
function. We have hardcoded a user object for simplicity, but in a real application, we would authenticate the user using a database or another authentication method.
The /profile
route is protected by authentication middleware. When a user requests this URL, the middleware checks for a valid JWT token in the request headers. If the token is valid, it returns the user’s payload data. If the token is invalid or expired, it returns an error message.
Now that we have added authentication to our API, we can test it using Postman or another API testing tool. We can simulate a login request by sending a POST request to http://localhost:3000/login
with a JSON payload containing the user’s email and password. The API will respond with a user object and a JWT token.
We can then use the token to access the protected /profile
route by sending a GET request to http://localhost:3000/profile
with an Authorization
header containing the token. The API will respond with the user’s payload data.
Adding Database Integration
Now that we have added authentication to our API, let’s integrate it with a database. We’ll use MongoDB as our database and the Mongoose library to interact with it.
To use Mongoose in our Express JS application, we first need to install the mongoose
package. We can do this by running the following command in our terminal:
npm install mongoose
Once we have installed the package, we can connect to our MongoDB database using Mongoose. Let’s create a new file called db.js
in our project directory where we will define our database connection:
const mongoose = require('mongoose');
const url = 'mongodb://localhost/mydatabase';
mongoose.connect(url, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('Database connected');
});
In this code snippet, we have imported the mongoose
package and defined the URL of our MongoDB database. We have used the mongoose.connect()
method to connect to the database and set some options to ensure Mongoose uses the latest URL parser and unified topology engine.
We have also defined event listeners for the error
and open
events of our database connection. If the connection encounters an error, we log it to the console. If the connection is successful, we log a message to the console.
Now that we have connected to our MongoDB database, we can define a schema for our user objects. Let’s create a new file called user.js
in our project directory where we will define our user schema:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
const userModel = mongoose.model('User', userSchema);
module.exports = userModel;
In this code snippet, we have created a new Mongoose schema for our user objects. The schema defines three fields: name
, email
, and password
. The required
property is set to true for all fields to ensure they are present when we save the user object to the database. The email
field is also set to unique
to ensure that each user has a unique email address.
We have then defined a Mongoose model for our schema and exported it.
Now that we have defined our user schema, let’s modify our auth.js
file to use the Mongoose model to authenticate users:
const userModel = require('./user');
// ...
router.post('/login', async (req, res) => {
const { email, password } = req.body;
// Authenticate user
const user = await userModel.findOne({ email, password });
if (!user) {
res.status(401).json({ message: 'Unauthorized' });
} else {
const token = auth.generateToken(user);
res.json({ user, token });
}
});
// ...
In this modified code snippet, we have imported our user
model and used the findOne()
method to find a user object with the given email and password. If the user is not found, we return an error message. If the user is found, we generate a JWT token and return the user object and token.
We have also added the async
keyword to our route function and awaited the findOne()
method to make sure it returns a Promise.
Finally, let’s modify our routes.js
file to save and retrieve user objects from our MongoDB database:
const express = require('express');
const router = express.Router();
const auth = require('./auth');
const userModel = require('./user');
router.post('/signup', async (req, res) => {
const { name, email, password } = req.body;
try {
const user = new userModel({ name, email, password });
await user.save();
res.json({ message: 'User created' });
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// ...
router.get('/users', async (req, res) => {
const users = await userModel.find({});
res.json(users);
});
module.exports = router;
In this code snippet, we have added a new /signup
route that creates a new user object and saves it to the database using the save()
method. We have also added a new /users
route that retrieves all user objects from the database using the find()
method.
We have wrapped our route functions inside a try-catch
block to handle potential errors. If an error occurs while creating or retrieving user objects, we return an error message with a 500 status code.
Testing The REST API
Now that we have built our REST API and integrated it with a database, let’s test it. We can use Postman or another API testing tool to send requests to our API and see how it responds.
For example, we can send a POST request to http://localhost:3000/signup
with a JSON payload containing a new user’s name, email, and password. The API will create a new user object in the database and return a “User created” message.
We can then send a POST request to http://localhost:3000/login
with the same email and password to generate a JWT token. The API will return the user object and token.
We can use the token to access the protected /profile
route by sending a GET request to http://localhost:3000/profile
with an Authorization
header containing the token. The API will return the user’s payload data.
We can also send a GET request to http://localhost:3000/users
to retrieve all user objects from the database. The API will return an array of user objects.
Conclusion
In this article, we have learned how to create a REST API with Express JS. We have covered the basics of creating routes, handling requests, and sending responses. We have also added authentication and database integration to our API.
By following the steps outlined in this article, you should now have a working REST API that you can use to build web and mobile applications. You can further customize your API by adding more routes, middleware functions, and integrating with other third-party services.
I hope you found this article helpful. Happy coding!
JIRA Cloud Api
Introduction As a project manager, I understand the importance of using tools and technology to streamline workflows and increase productivity. That’s why I want to share my experience using Jira Cloud API, a powerful tool for customizing, automating, and integrating Jira Cloud with other applications. In this article, I’ll introduce you to Jira Cloud API […]
How To Use The Cyberark Rest Api
Introduction: CyberArk REST API is one of the most powerful tools in the CyberArk suite of products. This API allows for seamless integration with third-party applications, making it possible to deploy automated processes that can help organizations reduce the risks associated with managing privileged accounts and passwords. As a software developer, I have personally experienced […]
What Is A Rest Api: Everything You Need To Know
Introduction: Hey guys, welcome to my new article! Today we are going to talk about RESTful APIs. Don’t worry if you’ve never heard of a RESTful API before, because we are going to explore what they are, how they work, how they are built, and their many benefits. You might be thinking: “I know what […]
How To Use GitHub REST Api
As a software developer, I know the importance of version control and keeping track of changes to code. That’s why I was thrilled when I first discovered Github API. Github API is a powerful tool used by developers to access and manipulate data within Github repositories. In this article, I’ll take a deep dive into […]