Explore my simple guidelines for building a REST API with Node.js and Express! Follow along to create a robust API from scratch. By the end, you'll have a fully functional tool for developing dynamics.
A REST API is like a bridge that lets you easily get and control data over the internet. It's called 'representational' because it shows the data in a way that's simple for other programs to work with. People often use REST APIs to access information in a database or make different programs talk to each other.
Think of a social media app wanting the newest posts. With a REST API, the app asks the API for the latest posts, and the API sends back the updates. This keeps the app current with the latest content, and the data is stored in a central place that many apps can use.
In this guide, we're using Node.js and Express to create our REST API. Node.js lets you build server-side apps with JavaScript, and Express is a handy tool for making APIs using Node.js. With these, it's simple to craft quick, scalable APIs that can handle various requests and workloads.
InitialIze the Project
Before starting the project, we need to setting up nodeJS to our PC/ Laptop.
After installing Node.js, open a terminal, go to your desired project location, and use the command below to start a new Node.js project
npm init
after entering this command it will ask a few questions about the project.
Next, we’ll install the Express library, which we’ll use to build our API. To install Express, run the following command in your terminal:
npm install express
After installing Express, the latest version is added to your package.json file under 'dependencies.' With Node.js and Express ready, let's create the foundation of our API. In your project directory, make a new file named 'app.js.' This file will be the starting point for our API, where we set up the Express app and define routes.
In 'app.js,' use the following code to import Express and create a new app:
const express = require('express');
const app = express();
Next, we’ll set up a simple route that will handle GET requests to the root path of our API. Add the following code to app.js
app.get('/', (req, res) => {
res.send('Hello, Jhon Doe!');
});
This piece of code sets up a way for a web server to respond when someone visits the main page of the API using a web browser. When a person sends a 'GET' request to the API's main page, the server will reply with a message saying 'Hello, Jhon Doe'.
This step involves adding code to the 'app.js' file to start the server, making the API accessible to users or clients. The specific code for starting the server is not provided, but you would typically see something like 'app. listen(port)' where 'port' is the number specifying which port the server should listen on for incoming requests.
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`API server listening on port ${PORT}`);
});
This piece of code determines the port on which the API will listen for incoming requests. It uses 'process.env.PORT' to dynamically set the port, allowing easy deployment on cloud platforms like AWS or Azure. If 'process.env.PORT' is not defined, it defaults to using port 3000.
That's all! You've successfully set up a basic API using Node.js and Express. To start the API, simply run the specified command in your terminal.
Now your app.js file looks like this:
after excuting this command:
node app.js
This will start the API server, and you should see the message “API server listening on port [PORT]” in the terminal.
Creating routes and managing requests sent to the server
In the previous section, we set up a basic API using Node.js and ExpressJS, and handled a GET request to the root path of the API. In this section, we’ll take a deeper dive into defining routes and handling different types of HTTP requests.
Routes are the endpoints of your API that clients can access to retrieve or manipulate data. In Express, you can define routes using the app.METHOD() functions, where METHOD is the HTTP method (e.g. GET, POST, PUT, DELETE) that the route will handle. For example, here's how you might define a route that handles GET requests to the /posts path
app.post('/api/add-data', (req, res) => {
// Code to handle the request and send a response
})
The 'req' (request) object holds details about the incoming request, like the method used, URL, headers, and request body for methods like POST or PUT. The 'res' (response) object provides methods, such as 'res.send()', 'res.json()', and 'res.render()', to send a response back to the client.
Here’s an example of how you might use the req and res objects to handle a GET request to the /get-all-data route and send a JSON response with a list of posts:
app.get('/api/get-all-data', (req, res) => {
const users = [
{ id: 1, name: 'User 1' },
{ id: 2, name: 'User 2' },
{ id: 3, name: 'User 3' }
];
res.json(users);
});
Besides GET, you can deal with other HTTP methods like POST, PUT, and DELETE using functions like app.post(), app.put(), and app.delete(). For instance, here's how you might manage a POST request to the /posts route for creating a new post:
app.post('/api/add-data', (req, res) => {
const newUser = {
id: 4,
name: req.body.name
};
// Add the new user to the list of users
res.json(newUser);
// or
res.status(200).json(newUser);
})
In this example, we’re using the req.body property to access the body of the POST request, which should contain the data for the new post. You can use similar techniques to handle PUT and DELETE requests, depending on the needs of your API.
Working with data and databases
There are many different ways you can store data in an API, depending on your needs and the complexity of your application. One simple approach is to store the data in-memory, using variables or arrays. For example, you could store a list of posts in a variable like this:
let users = [
{ id: 1, name: 'User 1' },
{ id: 2, name: 'User 2' },
{ id: 3, name: 'User 3' }
];
This approach is useful for testing and prototyping, but it has a few drawbacks. For one, the data is not persisted across API restarts, so you’ll lose all your data every time you stop and start the server. Additionally, in-memory data stores can become slow and inefficient as the data set grows, and they don’t scale well to support multiple clients.
A better way to store your data is by using a database. There are various databases like MongoDB, MySQL, PostgreSQL, and SQLite. Each has its pros and cons, so the right one for you depends on what you need.
In this tutorial, I’ll use MongoDB as an example. To use MongoDB with your API, you’ll need to install the MongoDB driver for Node.js and connect to a MongoDB database. Here’s an example of how you might do this:
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/api', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('Connected to MongoDB!');
});
This code utilizes the mongoose library to connect to a local MongoDB database. The 'db' variable signifies the connection, and 'db.on()' and 'db.once()' functions are used to manage connection errors and log a success message.
Once you have the database connection set up, you can start defining schemas and models to represent your data. Schemas define the structure of your data, and models are used to create and manipulate instances of your data. Here’s an example of how you might define a schema and model for posts:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
}
});
const User = mongoose.model('User', userSchema);
With the schema and model set up, you can use Mongoose's methods to perform operations like creating, reading, updating, and deleting data in the database. Here's an example of using the User model to get all Users from the database and send a JSON response to the client:
app.get('/api/user', (req, res) => {
User.find((err, users) => {
if (err) return res.status(500).send(err);
res.json(users);
});
});
To make sure the data sent to your API is correct and to handle errors effectively, you can use different methods. One easy option is using the joi library for data validation and express-async-errors for handling asynchronous errors. This example demonstrates how to validate the body of a POST request and manage any errors that might occur.
const Joi = require('joi');
app.post('/api/user', async (req, res) => {
// ensure the body is corrected
const schema = Joi.object().keys({
name: Joi.string().min(3).max(255).required(),
email: Joi.string().email()
});
const { error } = Joi.validate(req.body, schema);
// if an error occurred then return
if (error) return
res.status(400).send(error);
try {
const user = new User(req.body);
await user.save();
res.send(user);
} catch (error) {
res.status(500).send(error);
}
});
In this example, we use the joi library to set rules for the body of a POST request and check if the data follows these rules. If the data is wrong, we send a response with a status of 400 (Bad Request) and an error message. If the data is correct, we create a new post using the Post model and save it to the database. If any issues happen during the save, we catch the error and send a response with a status of 500 (Internal Server Error).
This will be a very simple article to get an idea about the Rest-API. I think this article supports you in getting a better idea about the concept of API.
Thank you. Have a bug-free day everyone.
Top comments (1)
While I am only a beginner at web development, it seems to me that there might be a typographical error in the following paragraph:
It seems to me that the above code should handle POST requests to the /posts path, not "GET" requests.