Skip to main content
arrow_back Back to blog
Backend 2025-05-20 — Daniel Flores

Building REST APIs with Node.js: Architecture and Best Practices

Building REST APIs with Node.js: Architecture and Best Practices

Node.js has become the standard for building fast, scalable REST APIs. A well-defined architecture is the difference between a maintainable project and an impossible-to-extend legacy.

Project structure

src/
├── middlewares/    # authentication, validation, errors
├── routes/        # endpoint definitions
├── controllers/   # request handling logic
├── services/      # business logic
├── repositories/  # data access layer
└── validators/    # validation schemas

Middleware pattern

Express relies on a chain of middlewares. Each receives req, res, next and can modify the request, respond, or delegate:

import { Request, Response, NextFunction } from 'express'

function authMiddleware(req: Request, res: Response, next: NextFunction) {
  const token = req.headers.authorization?.replace('Bearer ', '')
  if (!token) return res.status(401).json({ error: 'No token provided' })

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET!)
    req.user = decoded
    next()
  } catch {
    res.status(401).json({ error: 'Invalid token' })
  }
}

Clean controllers

Controllers only translate requests to data and delegate logic to services:

// controllers/product.controller.ts
export async function getProducts(req: Request, res: Response) {
  const { page = 1, limit = 10 } = req.query
  const result = await productService.list({ page: +page, limit: +limit })
  res.json(result)
}

Centralized error handling

// middlewares/error-handler.ts
export function errorHandler(err: Error, req: Request, res: Response, next: NextFunction) {
  const status = err instanceof AppError ? err.status : 500
  res.status(status).json({
    error: err.message,
    ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
  })
}

Conclusion

A well-architected Node.js API is modular, testable, and scalable. Clear layer separation and middleware usage lets you add functionality without breaking existing code.

Privacy Policy

Last updated: June 2026

1. Data Controller

Vunotek, based in Managua, Nicaragua, is the data controller for the personal information collected through this website. You can reach our data infrastructure team via the agency's official engineering email.

2. Data We Collect

We only collect information that you voluntarily provide through our technical contact form: full name, corporate email address, project type, estimated budget, and the technical description of your project requirements.

3. Purpose of Data Processing

Collected data is utilized exclusively to analyze your software requirements, draft technical and commercial proposals, and establish direct communication tracks with you or your company. We do not engage in automated tracking or marketing spam.

4. Data Storage & Security

Securing your information is our highest priority. All submitted details are safely processed using encrypted channels (HTTPS/SSL) and are stored in cloud environments guarded by strict access controls.

5. Third-Party Disclosures

Vunotek does not sell, rent, or trade your personal data. Information is only processed by essential cloud infrastructure tools required for system operations (such as trusted database managers or hosting pathways) under strict data processing standards.

6. Your Rights

You retain the right to access, update, restrict, or request the total deletion of your personal data from our systems at any time. To exercise these rights, simply submit a formal request from your corporate email into our direct engineering channels.