Building RESTful APIs with Node.js

Building RESTful APIs with Node.js

5 min read

Building RESTful APIs with Node.js

REST (Representational State Transfer) APIs are the backbone of modern web applications. Let’s explore how to build robust, scalable APIs with Node.js and Express.

Setting Up Your Project

First, initialize a new Node.js project:

mkdir my-api && cd my-api
npm init -y
npm install express cors helmet morgan dotenv

Project Structure

A well-organized project structure is crucial:

my-api/
├── src/
│   ├── controllers/
│   ├── routes/
│   ├── middleware/
│   ├── models/
│   ├── services/
│   └── utils/
├── tests/
├── .env
└── server.js

Creating Your First Endpoint

Here’s a basic Express server setup:

const express = require('express');
const cors = require('cors');
const helmet = require('helmet');

const app = express();

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

// Routes
app.get('/api/health', (req, res) => {
  res.json({ status: 'ok', timestamp: new Date() });
});

app.get('/api/users', async (req, res) => {
  try {
    const users = await UserService.getAll();
    res.json(users);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

REST API Best Practices

1. Use Proper HTTP Methods

2. Consistent URL Naming

Use nouns, not verbs:

3. Status Codes Matter

// Success
res.status(200).json(data);  // OK
res.status(201).json(data);  // Created
res.status(204).send();      // No Content

// Client Errors
res.status(400).json({ error: 'Bad Request' });
res.status(401).json({ error: 'Unauthorized' });
res.status(404).json({ error: 'Not Found' });

// Server Errors
res.status(500).json({ error: 'Internal Server Error' });

4. Error Handling Middleware

const errorHandler = (err, req, res, next) => {
  console.error(err.stack);
  
  res.status(err.status || 500).json({
    error: {
      message: err.message,
      ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
    }
  });
};

app.use(errorHandler);

Authentication with JWT

Secure your API with JSON Web Tokens:

const jwt = require('jsonwebtoken');

const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  
  if (!token) {
    return res.status(401).json({ error: 'Token required' });
  }
  
  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) return res.status(403).json({ error: 'Invalid token' });
    req.user = user;
    next();
  });
};

Conclusion

Building RESTful APIs requires attention to design patterns, security, and user experience. Start with a solid foundation, follow best practices, and iterate based on real-world usage.


Resources:

← Back to Blog