DEV Community

Cover image for Mastering REST API Best Practices with Node.js πŸš€
Biswajit Patra
Biswajit Patra

Posted on

1

Mastering REST API Best Practices with Node.js πŸš€

Let’s rewrite the same practices using Express.js, the go-to framework for building APIs in Node.js.


1. Foundational Design & Security πŸ›‘οΈ

Start with the basics: secure your API like it’s your grandma’s cookie recipe πŸͺ.

Authentication & Authorization πŸ”’

  • Authentication: Who are you? (Use tokens like JWTs)
  • Authorization: What are you allowed to do? (Role-based access control)

Example: Token Validation

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

const SECRET_KEY = "supersecretkey";

app.get('/protected', (req, res) => {
  const token = req.headers.authorization;
  if (!token) {
    return res.status(401).json({ error: "Token missing" });
  }
  try {
    jwt.verify(token, SECRET_KEY);
    res.status(200).json({ message: "Access granted" });
  } catch (err) {
    res.status(403).json({ error: "Invalid or expired token" });
  }
});
Enter fullscreen mode Exit fullscreen mode

Token validation like:

  • No token? 🚫 401 Unauthorized
  • Invalid token? πŸš“ 403 Forbidden

Rate Limiter 🚦

Prevent abuse by limiting the number of requests per user.

Example:

  • First 100 requests: 🏎️ Smooth sailing.
  • After 101st request: 🐒 Slow down, buddy.

Use express-rate-limit to limit requests.

Example:

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 1 * 60 * 1000, // 1 minute
  max: 5, // Limit each IP to 5 requests
  message: "Too many requests, please try again later.",
});

app.use('/limited', limiter, (req, res) => {
  res.json({ message: "You are within the limit!" });
});
Enter fullscreen mode Exit fullscreen mode

CORS Validation 🌐

Allow requests from trusted origins only.

Example:

const cors = require('cors');

app.use(cors({
  origin: 'https://trusted-site.com',
}));
Enter fullscreen mode Exit fullscreen mode

Trying from an untrusted site?

Response: "Sorry, not today! πŸ™…"


2. API Structure & Operations πŸ—οΈ

Clear CRUD Endpoints πŸ› οΈ

Examples:

  • GET /users – Get all users πŸ‘₯
  • POST /users – Create a new user ✍️
  • PUT /users/{id} – Update user πŸ› οΈ
  • DELETE /users/{id} – Delete user πŸ—‘οΈ

Confusing endpoints = confused developers = angry developers.

Manage users resource with Express.

Example:

let users = [];

app.use(express.json());

app.get('/users', (req, res) => {
  res.json(users);
});

app.post('/users', (req, res) => {
  const user = req.body;
  users.push(user);
  res.status(201).json(user);
});

app.put('/users/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const user = users.find(u => u.id === id);
  if (user) {
    Object.assign(user, req.body);
    res.json(user);
  } else {
    res.status(404).json({ error: "User not found" });
  }
});

app.delete('/users/:id', (req, res) => {
  users = users.filter(u => u.id !== parseInt(req.params.id));
  res.status(204).send();
});
Enter fullscreen mode Exit fullscreen mode

Status-Based Responses πŸ“œ

Always tell users what’s happening, politely.

Examples:

  • 200 OK – Yay, it worked! πŸŽ‰
  • 201 Created – Your shiny new resource is ready! πŸš€
  • 400 Bad Request – Uh-oh, something’s wrong with your input. 🀷
  • 500 Internal Server Error – Oops, we broke something. πŸ˜“

API Documentation πŸ“š

Use tools like Swagger or Postman.

Why?
Because an undocumented API is like IKEA furniture with no manual. 😭


Consistent Naming Conventions πŸ“

Stick to a pattern and never mix styles.

Example:

  • Good: /api/products
  • Bad: /API/getProducts
  • Ugly: /api/v1/proDuctsGetNow

3. Performance & Scalability πŸš€

Caching Strategy 🧊

Cache responses to save time (and server tears 😒).

Example:

GET /api/cached
Cache-Control: max-age=3600
Enter fullscreen mode Exit fullscreen mode

Use node-cache to cache responses.

Example:

const NodeCache = require('node-cache');
const cache = new NodeCache();

app.get('/cached', (req, res) => {
  const key = 'cachedResponse';
  if (cache.has(key)) {
    return res.json(cache.get(key));
  }
  const data = { message: "This response is cached!" };
  cache.set(key, data, 60); // Cache for 60 seconds
  res.json(data);
});
Enter fullscreen mode Exit fullscreen mode

Blue/Green Deployment πŸŒπŸ’š

Deploy without breaking anything. Test on a β€œblue” version while users stay on β€œgreen.”

Steps:

  1. Deploy the β€œblue” environment.
  2. Test it.
  3. Gradually switch traffic to blue.
  4. Celebrate with cake πŸŽ‚.

Logging Mechanism πŸ“

Log all requests using morgan.

Pro Tip:
Logs should be helpful, not a novel. Nobody likes wading through War and Peace. 🫠

Example:

const morgan = require('morgan');

app.use(morgan('combined'));
Enter fullscreen mode Exit fullscreen mode

4. Quality Assurance πŸ§ͺ

Comprehensive Test Cases βœ…

Test every scenario, even the absurd ones.

Example:

  • Does the API handle invalid inputs?
  • What happens if someone tries to upload a cat picture to /users? 🐱

Error Handling 🚨

Be friendly, even when rejecting users.

Example:

{
  "error": "Invalid email address. Did you mean: abc@gmail.com? πŸ€”"
}
Enter fullscreen mode Exit fullscreen mode

Input Validation πŸ›‚

Validate everything. Trust no one.

Example:

  • User sends "age": "twenty".
  • Response: "Age must be a number."

Conclusion:

A great API isn’t just functional; it’s intuitive, secure, and scalable. Treat your API like your house: keep it clean, secure, and easy to navigate. 🏠✨

And remember: Developers using your API will silently thank you (and maybe buy you coffee β˜•). Or, if you ignore best practices, you might just end up on their β€œwall of shame.” πŸ™ƒ


What’s your favorite REST API best practice? Share below!πŸ‘‡ Let’s chat! πŸŽ‰

Image of Timescale

πŸš€ pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applicationsβ€”without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up