
Building Production-Ready Node.js APIs: The Architecture Patterns We Use
The Layered Architecture Non-Negotiable
Every production Node.js API we build follows the same strict layer pattern: Routes → Controllers → Services. No exceptions. This separation is not dogmatic architecture purity — it is the pattern that makes the codebase testable, maintainable, and comprehensible to developers joining the project six months later.
Routes handle HTTP: extracting params, calling input validation middleware, delegating to a controller, and returning the response. They never touch the database. Controllers orchestrate the response: calling service functions, transforming data, building the JSON response. They never contain business logic. Services own everything else: all database access, all business rules, all third-party API calls. They never have access to req or res.
Error Handling Done Right
The most consistent source of production issues in Node.js APIs is inconsistent error handling. Every route should be wrapped with an async error handler that catches unhandled promise rejections and passes them to the Express error middleware. Every error middleware should return a consistent JSON response shape: success, error, statusCode — always.
Input Validation as Security
Input validation is not optional and it is not just about user experience. It is your first line of defence against injection attacks, type confusion vulnerabilities, and unexpected data shapes that cause runtime exceptions deep in your service layer. Every route that accepts user input must validate it before passing it to a controller.