Building a REST API with Node.js and Express
Tags: webdev, node, learning, api
Published: 2024-06-19 14:46:11

Creating a REST API is a common task for developers, especially when building web applications. In this tutorial, we will walk through the process of building a simple REST API using Node.js and Express. By the end, you'll have a basic understanding of how to set up routes, handle requests and responses, and connect to a database.

Prerequisites
Before we begin, make sure you have Node.js and npm installed on your machine. You can download and install them from the official Node.js website.

Setting Up the Project
Initialize the Project

First, create a new directory for your project and navigate into it:


mkdir rest-api
cd rest-api
Initialize a new Node.js project:

npm init -y
This will create a package.json file with default settings.

Install Dependencies

We will use Express for our web server framework and Mongoose to interact with MongoDB:


npm install express mongoose
Create the Server

Create a file named server.js and set up a basic Express server:

// server.js
const express = require('express');
const mongoose = require('mongoose');
const app = express();

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

// Routes
app.get('/', (req, res) => {
  res.send('Hello World!');
});

// Database connection
mongoose.connect('mongodb://localhost:27017/rest-api', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
})
.then(() => console.log('MongoDB connected'))
.catch((err) => console.error(err));

// Start the server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
This code sets up a basic Express server, connects to a MongoDB database, and defines a single route that returns "Hello World!".

Defining the Data Model
For this tutorial, we will create a simple API to manage a collection of "books". Each book will have a title, author, and number of pages.

Create the Book Model

In the models directory, create a file named Book.js:

// models/Book.js
const mongoose = require('mongoose');

const BookSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
  },
  author: {
    type: String,
    required: true,
  },
  pages: {
    type: Number,
    required: true,
  },
});

module.exports = mongoose.model('Book', BookSchema);
Creating CRUD Routes
Next, we will define routes to create, read, update, and delete books.

Set Up the Routes

In the routes directory, create a file named books.js:

// routes/books.js
const express = require('express');
const router = express.Router();
const Book = require('../models/Book');

// Get all books
router.get('/', async (req, res) => {
  try {
    const books = await Book.find();
    res.json(books);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

// Get a single book
router.get('/:id', getBook, (req, res) => {
  res.json(res.book);
});

// Create a new book
router.post('/', async (req, res) => {
  const book = new Book({
    title: req.body.title,
    author: req.body.author,
    pages: req.body.pages,
  });

  try {
    const newBook = await book.save();
    res.status(201).json(newBook);
  } catch (err) {
    res.status(400).json({ message: err.message });
  }
});

// Update a book
router.patch('/:id', getBook, async (req, res) => {
  if (req.body.title != null) {
    res.book.title = req.body.title;
  }
  if (req.body.author != null) {
    res.book.author = req.body.author;
  }
  if (req.body.pages != null) {
    res.book.pages = req.body.pages;
  }

  try {
    const updatedBook = await res.book.save();
    res.json(updatedBook);
  } catch (err) {
    res.status(400).json({ message: err.message });
  }
});

// Delete a book
router.delete('/:id', getBook, async (req, res) => {
  try {
    await res.book.remove();
    res.json({ message: 'Deleted Book' });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

// Middleware to get a book by ID
async function getBook(req, res, next) {
  let book;
  try {
    book = await Book.findById(req.params.id);
    if (book == null) {
      return res.status(404).json({ message: 'Cannot find book' });
    }
  } catch (err) {
    return res.status(500).json({ message: err.message });
  }

  res.book = book;
  next();
}

module.exports = router;
Integrate the Routes

Update server.js to use the new routes:

// server.js
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const booksRouter = require('./routes/books');

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

// Routes
app.use('/books', booksRouter);

// Database connection
mongoose.connect('mongodb://localhost:27017/rest-api', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
})
.then(() => console.log('MongoDB connected'))
.catch((err) => console.error(err));

// Start the server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
Testing the API
Now, you can use a tool like Postman or curl to test the API endpoints:

GET /books: Retrieve all books.
GET /books/
: Retrieve a specific book by ID.
POST /books: Create a new book.
PATCH /books/
: Update a specific book by ID.
DELETE /books/
: Delete a specific book by ID.

Small conclusion
In this tutorial, we built a simple REST API using Node.js and Express. We covered setting up the server, defining a data model, and creating CRUD routes. This basic setup can be expanded and customized to fit more complex requirements and applications. Happy coding!