Custom Base Controllers¶
Demonstrates how to extend Katal's Controller class to create reusable base classes with shared beforeHandle / afterHandle lifecycle hooks.
Source: examples/custom-base-controllers/app.ts
What This Covers¶
| Pattern | Class | What it does |
|---|---|---|
| Admin guard | AdminController |
Checks for admin token in beforeHandle, returns 403 if missing |
| API wrapper | ApiController |
Wraps all responses with { version, timestamp, data } via afterHandle |
| Auth guard | AuthenticatedController |
Verifies Bearer token in beforeHandle, sets this.user |
Run¶
cd examples/custom-base-controllers
bun run app.ts
Server starts on http://localhost:3000.
Key Pattern¶
abstract class AdminController extends Controller {
protected override async beforeHandle(): Promise<Response | null> {
const auth = this.context.request.headers.get("Authorization");
if (!auth?.includes("admin-token")) {
return this.error("Admin access required", 403);
}
return null; // continue to handle()
}
}
class GetAdminStatsController extends AdminController {
async handle() {
return this.success({ users: 42, revenue: 9000 });
}
}
Lifecycle Hooks¶
| Hook | Override | Return null to |
Return Response to |
|---|---|---|---|
beforeHandle() |
yes | continue to handle() |
short-circuit the request |
afterHandle(response) |
yes | — | transform or replace the response |