DEV Community

Cover image for Part 9: Building RESTful APIs with Node.js and Express
Dipak Ahirav
Dipak Ahirav

Posted on

Part 9: Building RESTful APIs with Node.js and Express

Node.js Series



In this part of our Node.js series, we will dive into one of the most powerful and essential components of modern web development: RESTful APIs. A RESTful API (Representational State Transfer) allows your server to interact with client applications by exposing structured endpoints and data. Using Express.js, we'll walk through building a simple REST API that handles CRUD (Create, Read, Update, Delete) operations.

What is a RESTful API?

A RESTful API is an architectural style for building web services that use HTTP requests to access and manipulate data. Each HTTP request method (GET, POST, PUT, DELETE) corresponds to a specific operation in CRUD:

  • GET: Retrieve data.
  • POST: Create new data.
  • PUT/PATCH: Update existing data.
  • DELETE: Remove data.

RESTful APIs are stateless, meaning that each API call from a client must contain all the necessary information for the server to fulfill the request.

Setting Up the Project

If you haven’t already, set up an Express project as we did in the earlier parts of this series. Install the necessary dependencies:

npm init -y
npm install express mongoose body-parser
Enter fullscreen mode Exit fullscreen mode

Now, create a simple Express server:

// app.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

const app = express();

// Middleware
app.use(bodyParser.json());

// MongoDB connection
mongoose.connect('mongodb://localhost:27017/restful_api', {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
db.once('open', () => {
  console.log('Connected to MongoDB');
});

const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
Enter fullscreen mode Exit fullscreen mode

Defining the Data Model

For this example, let’s create a simple data model for managing a collection of tasks. Each task will have a title and a description.

// taskModel.js
const mongoose = require('mongoose');

const taskSchema = new mongoose.Schema({
  title: { type: String, required: true },
  description: { type: String, required: true }
});

const Task = mongoose.model('Task', taskSchema);

module.exports = Task;
Enter fullscreen mode Exit fullscreen mode

Defining RESTful Routes

Now, let's create the routes for the API, which will handle all the CRUD operations for our tasks. In Express, these routes are linked to specific HTTP methods.

// app.js (continued)
const Task = require('./taskModel');

// 1. Get all tasks (GET /tasks)
app.get('/tasks', async (req, res) => {
  try {
    const tasks = await Task.find();
    res.status(200).json(tasks);
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
});

// 2. Get a single task by ID (GET /tasks/:id)
app.get('/tasks/:id', async (req, res) => {
  try {
    const task = await Task.findById(req.params.id);
    if (!task) {
      return res.status(404).json({ message: 'Task not found' });
    }
    res.status(200).json(task);
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
});

// 3. Create a new task (POST /tasks)
app.post('/tasks', async (req, res) => {
  const task = new Task({
    title: req.body.title,
    description: req.body.description
  });
  try {
    const newTask = await task.save();
    res.status(201).json(newTask);
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
});

// 4. Update a task by ID (PUT /tasks/:id)
app.put('/tasks/:id', async (req, res) => {
  try {
    const updatedTask = await Task.findByIdAndUpdate(
      req.params.id,
      {
        title: req.body.title,
        description: req.body.description
      },
      { new: true }
    );
    if (!updatedTask) {
      return res.status(404).json({ message: 'Task not found' });
    }
    res.status(200).json(updatedTask);
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
});

// 5. Delete a task by ID (DELETE /tasks/:id)
app.delete('/tasks/:id', async (req, res) => {
  try {
    const task = await Task.findByIdAndDelete(req.params.id);
    if (!task) {
      return res.status(404).json({ message: 'Task not found' });
    }
    res.status(200).json({ message: 'Task deleted successfully' });
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
});
Enter fullscreen mode Exit fullscreen mode

Testing Your API

To test your API, you can use tools like Postman or curl. Here are some sample requests you can try:

  1. Create a new task:

    • Method: POST
    • URL: http://localhost:3000/tasks
    • Body (JSON):
     {
       "title": "Learn Node.js",
       "description": "Complete the Node.js tutorial series"
     }
    
  2. Get all tasks:

    • Method: GET
    • URL: http://localhost:3000/tasks
  3. Get a task by ID:

    • Method: GET
    • URL: http://localhost:3000/tasks/:id
  4. Update a task:

    • Method: PUT
    • URL: http://localhost:3000/tasks/:id
    • Body (JSON):
     {
       "title": "Learn Express.js",
       "description": "Build RESTful APIs with Express"
     }
    
  5. Delete a task:

    • Method: DELETE
    • URL: http://localhost:3000/tasks/:id

Conclusion

Building RESTful APIs is a fundamental skill for modern web development. Express.js, combined with MongoDB, provides a powerful and flexible platform for creating scalable APIs that support various operations like creating, reading, updating, and deleting data.

In the next part of our series, we will explore deploying your Node.js application to the cloud and making it accessible to the world.

Stay tuned for more advanced Node.js development techniques!


Start Your JavaScript Journey

If you're new to JavaScript or want a refresher, visit my blog on BuyMeACoffee to get started with the basics.

πŸ‘‰ Introduction to JavaScript: Your First Steps in Coding

Series Index

Part Title Link
1 Server-Side Rendering (SSR) in React with Next.js Read
2 Ditch Passwords: Add Facial Recognition to Your Website with FACEIO Read
3 The Ultimate Git Command Cheatsheet Read
4 Top 12 JavaScript Resources for Learning and Mastery Read
5 Angular vs. React: A Comprehensive Comparison Read
6 Top 10 JavaScript Best Practices for Writing Clean Code Read
7 Top 20 JavaScript Tricks and Tips for Every Developer πŸš€ Read
8 8 Exciting New JavaScript Concepts You Need to Know Read
9 Top 7 Tips for Managing State in JavaScript Applications Read
10 πŸ”’ Essential Node.js Security Best Practices Read
11 10 Best Practices for Optimizing Angular Performance Read
12 Top 10 React Performance Optimization Techniques Read
13 Top 15 JavaScript Projects to Boost Your Portfolio Read
14 6 Repositories To Master Node.js Read
15 Best 6 Repositories To Master Next.js Read
16 Top 5 JavaScript Libraries for Building Interactive UI Read
17 Top 3 JavaScript Concepts Every Developer Should Know Read
18 20 Ways to Improve Node.js Performance at Scale Read
19 Boost Your Node.js App Performance with Compression Middleware Read
20 Understanding Dijkstra's Algorithm: A Step-by-Step Guide Read
21 Understanding NPM and NVM: Essential Tools for Node.js Development Read

Follow and Subscribe:

Top comments (0)