Middlewares

Middlewares in Nova are functions that run before the route handler. They can be applied globally, at the controller level, or at the method level.

Middleware Signature

Type TypeScript
type middlewareFn = (req: NovaRequest, reply: NovaResponse) => Promise<void> | void;

Levels of Middleware

1. Global Middleware — app.use()

Runs before every route handler in the application.

main.ts TypeScript
const app = await NovaFactory.create();

app.use(async (req, reply) => {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
});

2. Controller Middleware — @Middleware() on class

Runs before all route handlers in the controller.

Example TypeScript
import { Middleware, Controller } from '@abrahambass/nova';

const logMiddleware = async (req, reply) => {
  console.log('Controller middleware');
};

@Middleware(logMiddleware)
@Controller('/users')
class UserController { ... }

3. Method Middleware — @Middleware() on method

Runs before a specific route handler.

Example TypeScript
const validateAdmin = async (req, reply) => {
  if (!req.user?.isAdmin) {
    reply.status(403).send({ detail: 'Forbidden' });
  }
};

@Controller('/admin')
class AdminController {

  @Middleware(validateAdmin)
  @Delet('/:id')
  async deleteUser() { ... }
}

Execution Order

Middlewares execute in this order:

  1. Global middlewares (via app.use())
  2. Controller-level middlewares (via @Middleware() on class)
  3. Method-level middlewares (via @Middleware() on method)
  4. Auth guard (if @RequiresAuth() is present)
  5. Route handler
💡 Tip

You can stack multiple middlewares by passing them as arguments: @Middleware(fn1, fn2, fn3). They execute in the order provided.