Thin routes that declare endpoints and bind to controllers. Thin controllers that parse the request, call a service, send the response. Services for business logic. Middlewares for auth, validation, errors. One file per concern.
How should I structure Express routes and controllers?
More FAQs in How to Structure Express Routes and Controllers
Without services, controllers grow long and logic is duplicated. With services, controllers stay thin and services are reusable. You can also use services in cron jobs, webhooks, or other services without an HTTP context. Testable too.
For simple CRUD, controllers can call models directly. Add services when logic is non-trivial (rules, permissions, orchestration). Do not over-engineer simple CRUD; do not under-engineer complex logic.
Only endpoint declarations and bindings to controllers. router.get('/', controller.listPosts). No logic. No validation. No business rules. Routes are the map; controllers are the handlers; services do the work.
Still have questions?
Browse all our FAQs or reach out to our support team
Want to upskill yourself?
Your learning library
Small steps. Big possibilities.
Find your next course. Build something great.