Endpoints
In the REST API Template, endpoint organization depends on the architecture you chose:
- MVC: Routes are defined inside
src/routes, mapped to controllers insrc/controllers. - Modular: Routes and controllers are grouped by feature in
src/modules/<feature>.
This structure makes it easy to expand your API without cluttering your main app file.
Folder Overview
MVC Structure
src/
├── routes/
│ ├── user.route.js
│ └── health.route.js
└── controllers/
└── user.controller.jsModular Structure
src/
└── modules/
└── user/
├── user.route.js
└── user.controller.js- Routes define the HTTP endpoints (
GET /users,POST /users, etc.) - Controllers hold the logic that runs when those endpoints are called
Example Route File
MVC (src/routes/posts.route.js)
import express from "express"
import { createPost, getPosts } from "../controllers/posts.controller.js"
const router = express.Router()
router.get("/", getPosts)
router.post("/", createPost)
export default routerModular (src/modules/posts/posts.route.js)
import express from "express"
import { createPost, getPosts } from "./posts.controller.js"
const router = express.Router()
router.get("/", getPosts)
router.post("/", createPost)
export default routerExample Controller File
Depending on your architecture, this would be in src/controllers/posts.controller.js (MVC) or src/modules/posts/posts.controller.js (Modular).
import { ApiResponse } from "../../utils/ApiResponse.js" // Adjust path as needed
export const getPosts = (req, res) => {
const posts = [
{ id: 1, title: "Hello World" },
{ id: 2, title: "NeatNode Rocks" }
]
return ApiResponse.success(res, posts)
}
export const createPost = (req, res) => {
const { title } = req.body
return ApiResponse.success(res, { id: Date.now(), title })
}Route Registration
All route files are registered inside src/app.js under the comment markers:
// ROUTE_IMPORTS_START
// MVC example:
import userRouter from "./routes/user.route.js"
// Modular example:
// import userRouter from "./modules/user/user.route.js"
// ROUTE_IMPORTS_END
// ROUTE_USES_START
app.use("/api/users", userRouter)
// ROUTE_USES_ENDWhen the CLI removes CRUD examples, these sections are automatically stripped clean - keeping your app.js organized.
To add your own routes, simply add new imports between those markers or below them.
Creating a New Resource
Example: Add a products resource.
-
Create your controller:
src/controllers/products.controller.js -
Add routes:
src/routes/products.route.js -
Import and register them in
src/app.js:import productRouter from "./routes/products.route.js" app.use("/api/products", productRouter)
That’s it - your new API endpoints are ready.
CRUD Pattern
Each resource typically follows this pattern:
| Method | Path | Purpose |
|---|---|---|
GET | /api/items | Get all items |
GET | /api/items/:id | Get single item |
POST | /api/items | Create item |
PUT | /api/items/:id | Update item |
DELETE | /api/items/:id | Delete item |
Notes
- Controllers should handle business logic and return formatted responses using
ApiResponse. - Avoid direct DB logic inside route files - always delegate to controllers or services.
- Group routes by resource for maintainability.
Summary
| Folder | Purpose |
|---|---|
routes/ | HTTP route definitions |
controllers/ | Request handlers and response logic |
app.js | Central route registration point |
This modular pattern keeps every endpoint predictable, testable, and easy to extend as your API grows.