Middleware
Middleware runs before route handlers, with access to the request context.
Middleware functions execute before route handlers and have full access to the request context. They can modify the request, short-circuit the response, or pass control to the next handler.
NestMiddleware Interface
Middleware classes implement the NestMiddleware interface:
import { Injectable, NestMiddleware } from '@velajs/vela';
import type { Context, Next } from 'hono';
@Injectable()
class LoggingMiddleware implements NestMiddleware {
async use(c: Context, next: Next): Promise<Response | void> {
const start = Date.now();
console.log(`--> ${c.req.method} ${c.req.path}`);
await next();
const ms = Date.now() - start;
console.log(`<-- ${c.req.method} ${c.req.path} ${ms}ms`);
}
}Middleware receives Hono's Context object, giving you access to the full request and response API.
Applying Middleware
Decorator-based
Use @UseMiddleware() at the class or method level:
import { Controller, Get, UseMiddleware } from '@velajs/vela';
@Controller('spirits')
@UseMiddleware(LoggingMiddleware)
class SpiritsController {
@Get()
findAll() {
return [];
}
@Get(':id')
@UseMiddleware(AnotherMiddleware)
findOne(@Param('id') id: string) {
return { id };
}
}When applied at the class level, the middleware runs for all routes in the controller. When applied at the method level, it runs only for that route.
Global Middleware
Register middleware that runs for every request using useGlobalMiddleware():
const app = await VelaFactory.create(AppModule);
app.useGlobalMiddleware(LoggingMiddleware);Provider-based
Use the APP_MIDDLEWARE injection token to register global middleware through the module system:
import { Module, APP_MIDDLEWARE } from '@velajs/vela';
@Module({
providers: [
LoggingMiddleware,
{
provide: APP_MIDDLEWARE,
useExisting: LoggingMiddleware,
},
],
})
class AppModule {}This approach lets your middleware participate in dependency injection, so it can inject other providers.
Class vs Instance Middleware
Middleware can be a class or an instance:
- Class middleware — decorated with
@Injectable(), resolved through DI, can inject other providers - Instance middleware — a plain object with a
usemethod, does not participate in DI
// Class middleware (recommended)
@Injectable()
class AuthMiddleware implements NestMiddleware {
constructor(private authService: AuthService) {}
async use(c: Context, next: Next) {
const token = c.req.header('authorization');
if (!this.authService.verify(token)) {
return c.json({ error: 'Unauthorized' }, 401);
}
await next();
}
}Example: CORS Middleware
@Injectable()
class CorsMiddleware implements NestMiddleware {
async use(c: Context, next: Next) {
c.header('Access-Control-Allow-Origin', '*');
c.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
c.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (c.req.method === 'OPTIONS') {
return c.text('', 204);
}
await next();
}
}Modules
Modules organize the application into cohesive blocks of functionality.
Dependency Injection
Vela's IoC container provides automatic constructor injection with support for scopes and custom tokens.
Last updated on