Klement

Building a RESTful API with Node.js

2024-11-20 | Tag: Node.js

Learn how to create a RESTful API using Node.js and Express.

Introduction

Creating a RESTful API using Node.js and Express is straightforward and highly efficient. This post guides you through the process of building a basic API.

Steps

  1. Steps to Build the API:
mkdir restful-api && cd restful-api
npm init -y

Install Dependencies:

npm install express mongoose mysql2 jsonwebtoken dotenv body-parser bcrypt

Basic Express server setup:

const express = require('express');
    const app = express();
    const port = process.env.PORT || 3000;
    
    app.get('/', (req, res) => {
      res.send('Welcome to the RESTful API!');
    });
    
    app.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
    });

Using Environment Variables with dotenv:

// Create a .env file:
PORT=3000
MONGO_URI=mongodb://localhost:27017/mydatabase
JWT_SECRET=mysecretkey

Integrating dotenv into your project:

require('dotenv').config();
    const express = require('express');
    const app = express();
    
    const port = process.env.PORT;
    console.log('MongoDB URI:', process.env.MONGO_URI);
    app.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
    });

Using Mongoose with MongoDB:

Connect to MongoDB and define a Mongoose schema:

const mongoose = require('mongoose');
    
    mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
      .then(() => console.log('MongoDB connected'))
      .catch((err) => console.error('MongoDB connection error:', err));
    
    const itemSchema = new mongoose.Schema({
      name: String,
      quantity: Number,
    });
    
    const Item = mongoose.model('Item', itemSchema);
    
    module.exports = Item;

Create API endpoints with Mongoose:

const express = require('express');
    const app = express();
    const Item = require('./models/Item');
    app.use(express.json());
    
    // Get all items
    app.get('/items', async (req, res) => {
      const items = await Item.find();
      res.json(items);
    });
    
    // Add a new item
    app.post('/items', async (req, res) => {
      const item = new Item(req.body);
      await item.save();
      res.status(201).json(item);
    });
    
    // Delete an item
    app.delete('/items/:id', async (req, res) => {
      const { id } = req.params;
      await Item.findByIdAndDelete(id);
      res.status(204).send();
    });
    
    app.listen(process.env.PORT, () => {
      console.log('Server running');
    });

Using MySQL with Sequelize:

Connect to MySQL and define a model:

const { Sequelize, DataTypes } = require('sequelize');
    const sequelize = new Sequelize('database', 'username', 'password', {
      host: 'localhost',
      dialect: 'mysql',
    });
    
    sequelize.authenticate()
      .then(() => console.log('MySQL connected'))
      .catch((err) => console.error('MySQL connection error:', err));
    
    const Item = sequelize.define('Item', {
      name: { type: DataTypes.STRING },
      quantity: { type: DataTypes.INTEGER },
    });
    
    sequelize.sync();
    
    module.exports = Item;

Create API endpoints with Sequelize:

const express = require('express');
    const app = express();
    const Item = require('./models/Item');
    app.use(express.json());
    
    // Get all items
    app.get('/items', async (req, res) => {
      const items = await Item.findAll();
      res.json(items);
    });
    
    // Add a new item
    app.post('/items', async (req, res) => {
      const item = await Item.create(req.body);
      res.status(201).json(item);
    });
    
    // Delete an item
    app.delete('/items/:id', async (req, res) => {
      const { id } = req.params;
      await Item.destroy({ where: { id } });
      res.status(204).send();
    });
    
    app.listen(process.env.PORT, () => {
      console.log('Server running');
    });

JWT Authentication:

Authenticate users with JWT:

const jwt = require('jsonwebtoken');
    const express = require('express');
    const bcrypt = require('bcrypt');
    const app = express();
    app.use(express.json());
    
    const users = [];
    
    // Register user
    app.post('/register', async (req, res) => {
      const hashedPassword = await bcrypt.hash(req.body.password, 10);
      const user = { name: req.body.name, password: hashedPassword };
      users.push(user);
      res.status(201).send('User registered');
    });
    
    // Login user
    app.post('/login', async (req, res) => {
      const user = users.find(u => u.name === req.body.name);
      if (!user || !(await bcrypt.compare(req.body.password, user.password))) {
        return res.status(403).send('Access Denied');
      }
      const token = jwt.sign({ name: user.name }, process.env.JWT_SECRET);
      res.json({ token });
    });
    
    // Middleware to verify token
    const authenticate = (req, res, next) => {
      const token = req.headers.authorization?.split(' ')[1];
      if (!token) return res.status(401).send('Access Denied');
    
      try {
        const verified = jwt.verify(token, process.env.JWT_SECRET);
        req.user = verified;
        next();
      } catch {
        res.status(400).send('Invalid token');
      }
    };
    
    // Protected route
    app.get('/protected', authenticate, (req, res) => {
      res.send('This is a protected route');
    });
    
    app.listen(process.env.PORT, () => {
      console.log('Server running');
    });
Use tools like Postman or curl to test your API endpoints effectively.

Conclusion

This comprehensive setup demonstrates how to create a RESTful API using Node.js and Express, with examples for Mongoose, MySQL, JWT authentication, and environment variables. Extend it further with more features as needed.