Middleware
HTTP middlewares allow you to hook into the request/response cycle as an alternative to HTTP events. Its API allows you to use all middlewares from the Express/Connect framework.
A middleware can either be a class (which is instantiated by the dependency injection container) or a simple function.
import { HttpMiddleware, httpMiddleware, HttpRequest, HttpResponse } from '@deepkit/http'; class MyMiddleware implements HttpMiddleware { async execute(request: HttpRequest, response: HttpResponse, next: (err?: any) => void) { response.setHeader('middleware', '1'); next(); } } function myMiddlewareFunction(request: HttpRequest, response: HttpResponse, next: (err?: any) => void) { response.setHeader('middleware', '1'); next(); } new App({ providers: [MyMiddleware], middlewares: [ httpMiddleware.for(MyMiddleware), httpMiddleware.for(myMiddlewareFunction), ], imports: [new FrameworkModule] }).run();
Global
By using httpMiddleware.for(MyMiddleware) a middleware is registered for all routes, globally.
import { httpMiddleware } from '@deepkit/http'; new App({ providers: [MyMiddleware], middlewares: [ httpMiddleware.for(MyMiddleware) ], imports: [new FrameworkModule] }).run();
Per Controller
You can limit middlewares to one or multiple controllers in two ways. Either by using the @http.controller
or httpMiddleware.for(T).forControllers()
. excludeControllers
allow you to exclude controllers.
@http.middleware(MyMiddleware) class MyFirstController { } new App({ providers: [MyMiddleware], controllers: [MainController, UsersCommand], middlewares: [ httpMiddleware.for(MyMiddleware).forControllers(MyFirstController, MySecondController) ], imports: [new FrameworkModule] }).run();
Per Route Name
forRouteNames
along with its counterpart excludeRouteNames
allow you to filter the execution of a middleware per route names.
class MyFirstController { @http.GET('/hello').name('firstRoute') myAction() { } @http.GET('/second').name('secondRoute') myAction2() { } } new App({ controllers: [MainController, UsersCommand], providers: [MyMiddleware], middlewares: [ httpMiddleware.for(MyMiddleware).forRouteNames('firstRoute', 'secondRoute') ], imports: [new FrameworkModule] }).run();
Per Action/Route
To execute a middleware only for a certain route, you can either use @http.GET().middleware()
or
httpMiddleware.for(T).forRoute()
where forRoute has multiple options to filter routes.
class MyFirstController { @http.GET('/hello').middleware(MyMiddleware) myAction() { } } new App({ controllers: [MainController, UsersCommand], providers: [MyMiddleware], middlewares: [ httpMiddleware.for(MyMiddleware).forRoutes({ path: 'api/*' }) ], imports: [new FrameworkModule] }).run();
forRoutes()
allows as first argument several way to filter for routes.
{ path?: string; pathRegExp?: RegExp; httpMethod?: 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'PUT' | 'DELETE' | 'OPTIONS' | 'TRACE'; category?: string; excludeCategory?: string; group?: string; excludeGroup?: string; }
Path Pattern
path
supports wildcard *.
httpMiddleware.for(MyMiddleware).forRoutes({ path: 'api/*' })
RegExp
httpMiddleware.for(MyMiddleware).forRoutes({ pathRegExp: /'api/.*'/ })
HTTP Method
Filter all routes by a HTTP method.
httpMiddleware.for(MyMiddleware).forRoutes({ httpMethod: 'GET' })
Category
category
along with its counterpart excludeCategory
allow you to filter per route category.
@http.category('myCategory') class MyFirstController { } class MySecondController { @http.GET().category('myCategory') myAction() { } } httpMiddleware.for(MyMiddleware).forRoutes({ category: 'myCategory' })
Group
group
along with its counterpart excludeGroup
allow you to filter per route group.
@http.group('myGroup') class MyFirstController { } class MySecondController { @http.GET().group('myGroup') myAction() { } } httpMiddleware.for(MyMiddleware).forRoutes({ group: 'myGroup' })
Per Modules
You can limit the execution of a module for a whole module.
httpMiddleware.for(MyMiddleware).forModule(ApiModule)
Per Self Modules
To execute a middleware for all controllers/routes of a module where the middleware was registered use forSelfModules()
.
const ApiModule new AppModule({ controllers: [MainController, UsersCommand], providers: [MyMiddleware], middlewares: [ //for all controllers registered of the same module httpMiddleware.for(MyMiddleware).forSelfModules(), ], });
Timeout
All middleware needs to execute next()
sooner or later. If a middleware does not execute next()
withing a timeout, a warning is logged and the next middleware executed. To change the default of 4seconds to something else use timeout(milliseconds).
const ApiModule = new AppModule({ controllers: [MainController, UsersCommand], providers: [MyMiddleware], middlewares: [ //for all controllers registered of the same module httpMiddleware.for(MyMiddleware).timeout(15_000), ], });
Multiple Rules
To combine multiple filters, you can chain method calls.
const ApiModule = new AppModule({ controllers: [MyController], providers: [MyMiddleware], middlewares: [ httpMiddleware.for(MyMiddleware).forControllers(MyController).excludeRouteNames('secondRoute') ], });
Express Middleware
Almost all express middlewares are supported. Those who access certain request methods of express are not yet supported.
import * as compression from 'compression'; const ApiModule = new AppModule({ middlewares: [ httpMiddleware.for(compress()).forControllers(MyController) ], });