DEV Community

Cover image for Building an Express API with Logging and Rate Limiting
Mohammed jobair Hossain
Mohammed jobair Hossain

Posted on

Building an Express API with Logging and Rate Limiting

When building an API, two important things often get overlooked by beginners: logging and rate limiting.
In this blog, we’ll explore why they matter, and how to add them to a Node.js Express server.

1. Why Logging Matters

Logging is like your app’s diary — it keeps track of important events, errors, and activity happening in your application.

In production, logs can help you:

  • Debug issues quickly.
  • Track suspicious activity.
  • Monitor server performance.
const { createLogger, format, transports } = require("winston");

const logger = createLogger({
  level: "info",
  format: format.combine(
    format.timestamp(),
    format.printf(({ level, message, timestamp }) => {
      return `${timestamp} [${level.toUpperCase()}]: ${message}`;
    })
  ),
  transports: [
    new transports.Console(),
    new transports.File({ filename: "logs/server.log" })
  ]
});

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

2. Why Rate Limiting Matters

Rate limiting prevents a single user (or bot) from overwhelming your server with too many requests.

It helps protect against:

  • Brute force attacks
  • DDoS (Distributed Denial-of-Service) attempts
  • Server overload
const rateLimit = require("express-rate-limit");
const logger = require("./logger");

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  limit: 10, // Max 10 requests per IP
  standardHeaders: true,
  legacyHeaders: false,
  handler: (req, res) => {
    logger.info(`Rate limit exceeded for IP: ${req.ip}`);
    res.status(429).send({
      error: "Too many requests, please try again later.",
      rateLimit: {
        limit: 10,
        remaining: 0,
        resetTime: new Date(Date.now() + 15 * 60 * 1000).toISOString()
      }
    });
  }
});

module.exports = limiter;

Enter fullscreen mode Exit fullscreen mode

📌 This allows 10 requests per IP every 15 minutes. When the limit is exceeded, it logs the IP and returns a 429 error.

3. Putting It All Together

We’ll build a small Express server that uses both logging and rate limiting.

const express = require("express");
const limiter = require("./limiter");
const logger = require("./logger");

const app = express();

// Apply rate limiter to all routes
app.use(limiter);

// Basic route
app.get("/", (req, res) => {
  logger.info(`Request to / from IP: ${req.ip}`);
  res.send("Hello, World!");
});

// Start server
const PORT = 3000;
app.listen(PORT, () => {
  logger.info(`Server is running on http://localhost:${PORT}`);
});

Enter fullscreen mode Exit fullscreen mode

Top comments (0)