Backend
Routes
Route file conventions and middleware composition.
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()
// Shared middleware instances for this 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 useBookingRoute from './booking.route'
import useOrganizationRoute from './organization.route'
import useUserRoute from './user.route'
import useServiceRoute from './service.route'
// ...
const router = Router()
router.use('/auth', useAuthRoute())
router.use('/bookings', useBookingRoute())
router.use('/organizations', useOrganizationRoute())
router.use('/users', useUserRoute())
router.use('/services', useServiceRoute())
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:
// Apply auth on specific routes
router.get('/', authMiddleware, getBookings)
router.post('/', authMiddleware, createBooking)
// Mix auth levels on the same resource
router.get('/public-stats', getPublicStats) // no auth
router.get('/private', authMiddleware, getPrivate) // auth required
router.delete('/:id', adminMiddleware, deleteItem) // admin only
REST Conventions
| Operation | Method | Path |
|---|---|---|
| List | GET | /bookings |
| Get one | GET | /bookings/:id |
| Create | POST | /bookings |
| Full replace | PUT | /bookings/:id |
| Partial update | PATCH | /bookings/:id |
| Delete (soft) | DELETE | /bookings/:id |
| Sub-resource action | PATCH | /bookings/:id/cancel |
| Nested resource | POST | /bookings/:id/payment |