Node / Express Guide
Routes
Route file conventions, router factory pattern, and REST method conventions.
Routes wire HTTP paths to controller functions and compose middleware. Each resource has its own route file.
Pattern
Route files export a factory function that returns an Express Router:
// src/routes/auth.route.ts
import { Router } from 'express'
import { useAuthController } from '../controllers/auth.controller'
import { useRevokedTokenRepo } from '../repositories/revoked-token.repo'
import { authenticate } from '@codisolutions23/node-utils'
import { resolveOptionalTenant } from '../middleware/tenant.middleware'
import { accessTokenSecret } from '../config'
export default function useAuthRoute() {
const router = Router()
const { existsByJti } = useRevokedTokenRepo()
const { login, refreshToken, logout, getCurrentUser } = useAuthController()
// Build middleware instances once per router
const authMiddleware = authenticate(accessTokenSecret, existsByJti)
router.post('/login', resolveOptionalTenant, login)
router.post('/refresh', refreshToken)
router.get('/user', authMiddleware, getCurrentUser)
router.delete('/logout', authMiddleware, logout)
return router
}
Route Index
All routes are mounted in src/routes/index.ts under /api/:
// src/routes/index.ts
import { Router } from 'express'
import useAuthRoute from './auth.route'
import useUserRoute from './user.route'
import useResourceRoute from './resource.route'
const router = Router()
router.use('/auth', useAuthRoute())
router.use('/users', useUserRoute())
router.use('/resources', useResourceRoute())
export default router
Mounted in src/app.ts:
app.use('/api', routes)
Middleware Composition
Middleware is composed per route — not globally applied unless it truly applies to all routes:
// src/routes/resource.route.ts
export default function useResourceRoute() {
const router = Router()
const { existsByJti } = useRevokedTokenRepo()
const { getAll, create, update, remove } = useResourceController()
const authMiddleware = authenticate(accessTokenSecret, existsByJti)
const branchManagerMiddleware = requireBranchManagerOrAbove(accessTokenSecret, existsByJti)
const adminMiddleware = requireAdmin(accessTokenSecret, existsByJti)
router.get('/', authMiddleware, getAll)
router.post('/', branchManagerMiddleware, create)
router.patch('/:id', branchManagerMiddleware, update)
router.delete('/:id', adminMiddleware, remove)
return router
}
REST Conventions
| Operation | Method | Path |
|---|---|---|
| List | GET | /resources |
| Get one | GET | /resources/:id |
| Create | POST | /resources |
| Full replace | PUT | /resources/:id |
| Partial update | PATCH | /resources/:id |
| Soft delete | DELETE | /resources/:id |
| Sub-resource action | PATCH | /resources/:id/action |
| Nested resource | POST | /resources/:id/related |