Routing
GamanJS uses composeRouter to declaratively define all application routes. The router supports all HTTP methods, route grouping, per-route middleware, and per-route exception handlers.
Basic Usage
Section titled “Basic Usage”import { composeRouter } from 'gaman/compose';import AppController from './module/controllers/AppController';
export default composeRouter((r) => { r.get('/', [AppController, 'HelloWorld']); r.post('/users', [AppController, 'CreateUser']);});HTTP Methods
Section titled “HTTP Methods”All standard HTTP methods are available:
export default composeRouter((r) => { r.get('/resource', handler); r.post('/resource', handler); r.put('/resource/:id', handler); r.patch('/resource/:id', handler); r.delete('/resource/:id', handler); r.head('/resource', handler); r.options('/resource', handler); r.all('/resource', handler); // GET, POST, PUT, DELETE, PATCH});Custom Methods
Section titled “Custom Methods”r.match(['GET', 'POST'], '/custom', handler);Handler Types
Section titled “Handler Types”A handler can be a function directly or a Controller tuple:
Function Handler
Section titled “Function Handler”r.get('/ping', (ctx) => { return Res.message('pong');});Controller Handler (Recommended)
Section titled “Controller Handler (Recommended)”import UserController from './module/controllers/UserController';
r.get('/users', [UserController, 'GetAll']);r.get('/users/:id', [UserController, 'GetById']);r.post('/users', [UserController, 'Create']);Format: [ControllerFactory, 'MethodName']
Route Parameters
Section titled “Route Parameters”Use :name for dynamic parameters:
r.get('/users/:id', [UserController, 'GetById']);r.get('/posts/:postId/comments/:commentId', [PostController, 'GetComment']);Access in handler via ctx.param('id') or ctx.params.
Route Grouping
Section titled “Route Grouping”Group routes with a shared prefix:
export default composeRouter((r) => { r.group('/api/v1', (api) => { api.get('/users', [UserController, 'GetAll']); api.post('/users', [UserController, 'Create']);
api.group('/admin', (admin) => { admin.get('/dashboard', [AdminController, 'Dashboard']); }); });});Resulting routes:
GET /api/v1/usersPOST /api/v1/usersGET /api/v1/admin/dashboard
Route Middleware
Section titled “Route Middleware”Add per-route middleware using .middleware() chaining:
import AuthMiddleware from './module/middlewares/AuthMiddleware';
export default composeRouter((r) => { // Route without middleware r.get('/public', [AppController, 'Public']);
// Route with middleware r.get('/protected', [AppController, 'Protected']) .middleware(AuthMiddleware());
// Multiple middleware r.post('/admin/action', [AdminController, 'DoAction']) .middleware(AuthMiddleware()) .middleware(RateLimitMiddleware());});Group Middleware
Section titled “Group Middleware”Automatically applied to all routes in the group:
r.group('/admin', (admin) => { admin.get('/dashboard', [AdminController, 'Dashboard']); admin.get('/users', [AdminController, 'Users']);}).middleware(AuthMiddleware());Route Exception Handler
Section titled “Route Exception Handler”Override error handling for specific routes:
import { composeException } from 'gaman/compose';
const CustomErrorHandler = composeException((error, ctx) => { return Res.send({ detail: error.message }, 500);});
r.get('/risky', [AppController, 'Risky']) .exception(CustomErrorHandler);Route Naming
Section titled “Route Naming”Give routes a name for reference:
r.get('/users/:id', [UserController, 'GetById']) .name('users.show');Full Chaining
Section titled “Full Chaining”All route methods return a RouteDefinition supporting chaining:
r.post('/users', [UserController, 'Create']) .middleware(AuthMiddleware()) .middleware(ValidateMiddleware()) .exception(CustomErrorHandler) .name('users.create');