Skip to content

Middleware

Danny SMc edited this page Dec 6, 2021 · 6 revisions

The middleware that Turbo offers is an abstracted version of a standard middleware, where instead a request handler is used to process the request, due to the way services are configured you can simply create a response for the service your middleware is attached to, and execute it to run the response.

The way middleware is written is as follows, you have a class (this is to allow @Inject functionality), then you would create an async handle method, which will take the context of the service you want to add a middleware for, from here you use the decorator @Auth.Use(middlewareClass) on the controller class, this will tell the framework to use the middleware class when the controller is called for all route methods inside.

See the Authentication page for using middleware in your controller.


Example Middleware (HttpPlugin)

The below is an example middleware class for the Http plugin.

import { Middleware, Http, AbstractMiddleware } from '../../src';

@Middleware('http.auth', { priority: 1 })
export default class DemoAuthMiddleware extends AbstractMiddleware implements Http.IMiddleware {
	public async handle(context: Http.Context): Promise<boolean> {
		context.setAuth({ user: 'public', email: 'noreply@example.com', roles: ['admin'] });

		// We return true, saying that we should continue, returning false
		// means we want to stop processing for this route.
		return true;
	}
}

As you can see we give the middleware a unique name, and then some options, the options are passed in via the abstract class, so you can call them as this.options from inside the handle method.

We then implement the Http.IMiddleware interface, worth noting that all services should implement their own middleware interface to help with type hinting. As part of the interface it defines the context type, which is Http.Context.


Global Middleware

Sometimes you may want to add a middleware to all routes and services, of course, this means that you will need to manually check which service is being used and how to respond, but can always come in handy if you simply need to add authentication to all routes. To do this, when defining the decorator, pass true as the third argument, like so (remember not to implement any types here, otherwise you will be given the wrong type hinting):

import { Middleware, Http, AbstractMiddleware } from '../../src';

@Middleware('global.middleware', { /* Options */ }, true)
export default class GlobalMiddleware extends AbstractMiddleware {
	public async handle(context: any): Promise<boolean> {
		context?.setAuth({ user: 'public', email: 'noreply@example.com', roles: ['admin'] });
		return true;
	}
}

Service-level Middleware

Similar to the above, if you need to create a global middleware on the service level, you can do so by passing the middleware's unique name, this should be defined by each middleware, but for the HttpPlugin it is http and for the WsPlugin it is ws, see below:

import { Middleware, Http, AbstractMiddleware } from '../../src';

@Middleware('http.middleware', { /* Options */ }, 'http')
export default class HttpServiceMiddleware extends AbstractMiddleware implements Http.IMiddleware {
	public async handle(context: Http.Context): Promise<boolean> {
		context.setAuth({ user: 'public', email: 'noreply@example.com', roles: ['admin'] });
		return true;
	}
}

Features

Plugins

Future Plans

Resources

Clone this wiki locally