🚧 AvleonJs is in active development and not ready for production use.

Middleware

Creation & usages of avleon middleware

Middleware runs before your route handler and can inspect or modify the request, or reject it outright.

npx avleon make:middleware logger

The command generates:

src/middlewares/logger.middleware.ts
import { AppMiddleware, AvleonMiddleware, IRequest, IResponse } from '@avleon/core';

@AppMiddleware
export class LoggerMiddleware extends AvleonMiddleware {
  /**
   * Return the request to continue, or throw to stop the pipeline.
   */
  async invoke(req: IRequest, res?: IResponse) {
    console.log('url:', req.url);
    return req;
  }
}

A middleware extends AvleonMiddleware and implements invoke. Returning the request continues the pipeline; throwing an HttpExceptions error stops it:

import { AppMiddleware, AvleonMiddleware, IRequest, HttpExceptions } from '@avleon/core';

@AppMiddleware
export class ApiKeyMiddleware extends AvleonMiddleware {
  async invoke(req: IRequest) {
    if (req.headers['x-api-key'] !== process.env.API_KEY) {
      throw HttpExceptions.unauthorized('Invalid API key');
    }
    return req;
  }
}

Applying middleware

Middleware can be applied at three levels.

Global

Runs for every request. Note the plural — useMiddlewares:

app.ts
import { Avleon } from '@avleon/core';
import { LoggerMiddleware } from './middlewares/logger.middleware';

const app = Avleon.createApplication();

app.useMiddlewares([LoggerMiddleware]);

export default app;

Controller scoped

Runs for every route on that controller:

import { ApiController, Get, UseMiddleware } from '@avleon/core';
import { LoggerMiddleware } from '../middlewares/logger.middleware';

@UseMiddleware(LoggerMiddleware)
@ApiController('/home')
export class HomeController {
  @Get()
  sayHello() {
    return 'Hello';
  }
}

Route scoped

Runs for a single route:

import { ApiController, Get, UseMiddleware } from '@avleon/core';
import { LoggerMiddleware } from '../middlewares/logger.middleware';

@ApiController('/home')
export class HomeController {
  @UseMiddleware(LoggerMiddleware)
  @Get()
  sayHello() {
    return 'Hello';
  }
}

UseMiddleware also accepts an array:

@UseMiddleware([LoggerMiddleware, ApiKeyMiddleware])

Note: @UseMiddleware must sit above @ApiController on a class, and above the route decorator on a method — decorators apply bottom-up.