Layered structure for a scalable Express API
separation of concerns and testability.
routes map URLs, controllers handle HTTP, services hold business logic, data layer talks to the DB; keep each layer ignorant of HTTP except controllers.
WHAT THIS TESTS This assesses your ability to organize a growing API for maintainability, testability, and clear ownership, rather than piling everything into route callbacks.
A GOOD ANSWER COVERS The routing layer maps HTTP methods and paths to handlers and attaches middleware such as auth and validation; it contains no business logic. Controllers are the HTTP boundary: they read parameters, body, and headers, call into services, and shape the response and status code, but they stay thin. Services hold the actual business rules and orchestration, and crucially they know nothing about Express request or response objects, which makes them reusable and easy to unit-test. The data access layer, often a repository, isolates all database interaction, so the rest of the app deals in domain objects rather than queries. Dependencies flow one direction, downward, so you can test services with mocked repositories and swap the database without touching controllers.
COMMON WRONG ANSWERS Writing fat route handlers that validate input, apply business logic, and run raw queries together. Leaking the request or response object into services so they become untestable. Creating layers in name only while still coupling everything, or over-engineering with needless abstraction for a tiny API.
LIKELY FOLLOW-UPS Where validation and error handling belong, how dependency injection aids testing, how to keep cross-cutting concerns like logging out of business logic, and when a simpler structure is appropriate.
ONE CONCRETE EXAMPLE A POST to create a user flows through a route that runs validation middleware, into a UserController that extracts the body and calls userService.create, into a service that enforces uniqueness rules and hashes the password, and finally into a userRepository that performs the insert. To test the uniqueness rule you call the service with a stub repository and never start an HTTP server, because no layer below the controller depends on Express.
Read the original → github.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.