Lewati ke konten

Middlewares

Middleware di GamanJS berjalan sebelum handler route dan bisa melakukan pengecekan, modifikasi context, atau menghentikan request sebelum sampai ke controller.

src/modules/app/middlewares/AppMiddleware.ts
import { composeMiddleware } from 'gaman/compose';
export default composeMiddleware(async (ctx, next) => {
// Logic sebelum handler
console.log(`[${ctx.request.method}] ${ctx.path}`);
// Lanjutkan ke handler / middleware berikutnya
return next();
});

composeMiddleware mengembalikan factory function — harus dipanggil () saat didaftarkan.

Jika middleware ingin menghentikan request (misal: auth gagal), jangan panggil next(), kembalikan response menggunakan ctx.send():

import { composeMiddleware } from 'gaman/compose';
export default composeMiddleware(async (ctx, next) => {
const token = ctx.header('Authorization');
if (!token) {
return ctx.send({ message: 'Unauthorized' }).unauthorized();
}
// Token valid, lanjutkan
return next();
});

Daftarkan di defineBootstrap via app.mount():

import { defineBootstrap } from 'gaman';
import router from './router';
import LogMiddleware from './modules/app/middlewares/LogMiddleware';
defineBootstrap(async (app) => {
// Middleware global — berjalan di SEMUA route
app.mount(LogMiddleware());
app.mount(router);
app.mountServer({ http: 3431 });
});

Daftarkan langsung di route definition:

import { composeRouter } from 'gaman/compose';
import AuthMiddleware from './modules/app/middlewares/AuthMiddleware';
import UserController from './modules/app/controllers/UserController';
export default composeRouter((r) => {
r.get('/profile', [UserController, 'Profile'])
.middleware(AuthMiddleware());
});

Berlaku ke semua route dalam group:

r.group('/admin', (admin) => {
admin.get('/dashboard', [AdminController, 'Dashboard']);
admin.get('/settings', [AdminController, 'Settings']);
}).middleware(AuthMiddleware());

Middleware memiliki priority yang mengatur urutan eksekusi. Priority lebih rendah (angka lebih kecil) dijalankan lebih dulu.

import { Priority } from 'gaman/utils';
PriorityNilaiKeterangan
MONITOR0Paling awal, untuk logging/monitoring
VERY_HIGH1Sangat tinggi
HIGH2Tinggi
NORMAL3Default
LOW4Rendah
VERY_LOW5Paling akhir
export default composeMiddleware(
async (ctx, next) => {
return next();
},
{ priority: Priority.NORMAL }, // default config
);
app.mount(LogMiddleware({ priority: Priority.MONITOR }));
app.mount(AuthMiddleware({ priority: Priority.HIGH }));

Middleware bisa menerima konfigurasi custom:

import { composeMiddleware } from 'gaman/compose';
type CorsConfig = {
origin: string;
methods: string[];
};
export default composeMiddleware<CorsConfig>(
async (ctx, next) => {
ctx.headers.set('Access-Control-Allow-Origin', '*');
return next();
},
{
origin: '*',
methods: ['GET', 'POST'],
priority: Priority.VERY_HIGH,
},
);

Penggunaan:

app.mount(CorsMiddleware({ origin: 'https://example.com' }));

Middleware bisa menyimpan data yang bisa diakses oleh handler:

export default composeMiddleware(async (ctx, next) => {
const user = await verifyToken(ctx.header('Authorization'));
ctx.set('user', user); // Simpan ke context
return next();
});

Akses di controller:

GetProfile(ctx) {
const user = ctx.get('user'); // Ambil dari context
return ctx.send(user).ok();
}