Routing
GamanJS menggunakan composeRouter untuk mendefinisikan semua route aplikasi secara deklaratif. Router mendukung semua HTTP method, route grouping, middleware per-route, dan exception handler per-route.
Penggunaan Dasar
Section titled “Penggunaan Dasar”import { composeRouter } from 'gaman/compose';import AppController from './controllers/AppController';
export default composeRouter((r) => { r.get('/', [AppController, 'HelloWorld']); r.post('/users', [AppController, 'CreateUser']);});HTTP Methods
Section titled “HTTP Methods”Semua HTTP method standar tersedia:
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);Tipe Handler
Section titled “Tipe Handler”Handler bisa berupa function langsung atau tuple Controller:
Function Handler
Section titled “Function Handler”r.get('/ping', (ctx) => { return ctx.send('pong').ok();});Controller Handler (Rekomendasi)
Section titled “Controller Handler (Rekomendasi)”import UserController from './controllers/UserController';
r.get('/users', [UserController, 'GetAll']);r.get('/users/:id', [UserController, 'GetById']);r.post('/users', [UserController, 'Create']);Format: [ControllerFactory, 'NamaMethod']
Route Parameters
Section titled “Route Parameters”Gunakan :nama untuk parameter dinamis:
r.get('/users/:id', [UserController, 'GetById']);r.get('/posts/:postId/comments/:commentId', [PostController, 'GetComment']);Akses di handler via ctx.param('id') atau ctx.params.
Route Grouping
Section titled “Route Grouping”Grupkan route dengan prefix yang sama:
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']); }); });});Route yang dihasilkan:
GET /api/v1/usersPOST /api/v1/usersGET /api/v1/admin/dashboard
Route Middleware
Section titled “Route Middleware”Tambahkan middleware per-route menggunakan chaining .middleware():
import AuthMiddleware from './middlewares/AuthMiddleware';
export default composeRouter((r) => { // Route tanpa middleware r.get('/public', [AppController, 'Public']);
// Route dengan 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”Otomatis berlaku ke semua route dalam 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 per-route:
import { composeException } from 'gaman/compose';
const CustomErrorHandler = composeException((error, ctx) => { return ctx.send({ detail: error.message }).error();});
r.get('/risky', [AppController, 'Risky']) .exception(CustomErrorHandler);Global Router Hooks
Section titled “Global Router Hooks”Kamu bisa mendaftarkan middleware atau exception handler global khusus untuk satu router:
export default composeRouter((r) => { r.mountMiddleware(LogMiddleware()); r.mountException(CustomErrorHandler);
r.get('/', [AppController, 'render']);});Mounting Router Eksternal
Section titled “Mounting Router Eksternal”Di Dalam Router Lain
Section titled “Di Dalam Router Lain”import UserRouter from '../user/UserRouter';
export default composeRouter((r) => { r.mountRouter('/users', UserRouter);});Di Dalam defineBootstrap
Section titled “Di Dalam defineBootstrap”Router yang dibuat dengan composeRouter dapat dipanggil dengan prefix string saat melakukan mount di defineBootstrap:
import UserRouter from './modules/user/UserRouter';
defineBootstrap(async (app) => { app.mount(UserRouter('/user'));});Service Injection
Section titled “Service Injection”Kamu bisa menyuntikkan (inject) service ke dalam controller menggunakan r.mountService(). Service ini akan diteruskan ke factory function controller.
import { composeRouter } from 'gaman/compose';import { AppService } from './services/AppService';import AppController from './controllers/AppController';
export default composeRouter((r) => { // Inject service r.mountService({ appService: AppService(), });
r.get('/', [AppController, 'render']);});Chaining Lengkap
Section titled “Chaining Lengkap”Semua method route mengembalikan RouteDefinition yang mendukung chaining:
r.post('/users', [UserController, 'Create']) .middleware(AuthMiddleware()) .middleware(ValidateMiddleware()) .exception(CustomErrorHandler) .name('users.create');