Interceptors
Interceptors are middleware functions that are configured to run before or after an action. They can be used for logging, authorization, etc...
Kikwit supports defining interceptors using decorators on the controller or action levels. Controller interceptors apply to all controller actions. Action interceptors apply to the decorated action only.
Interceptors have the same signature as controller actions, they accept a single Context argument.
Before interceptors
Before interceptors are specified using the @before(...interceptors)
decorator.
'use strict';
import { before, controller, get } from 'kikwit';
@before(authenticate)
@controller
export class Home {
@get
index(context) {
context.sendJSON(context.locals);
}
@before(authorize)
@get
details(context) {
context.sendJSON(context.locals);
}
@before(authorize)
@get
info(context) {
context.sendJSON(context.locals);
}
@before(greet, authorize)
@get
hello(context) {
context.sendJSON(context.locals);
}
}
function authenticate(context) {
context.locals.userId = Math.trunc(Math.random() * 1000000);
context.next();
}
function authorize(context) {
context.locals.authorized = (context.locals.userId % 2 == 0);
if (!context.locals.authorized) {
return context.sendStatus(403, JSON.stringify(context.locals));
}
context.next();
}
function greet(context) {
context.locals.greeted = true;
return context.skipToAction();
}
After interceptors
After interceptors are specified using the @after(...interceptors)
decorator.
import { after, get, inject } from 'kikwit';
@after(addRandomHeader)
export class Products {
@inject('myService')
@get
list(context) {
context.services.myService.getProducts().then(products => {
// HTTP response will contain an 'X-RANDOM-NUMBER' header
context.sendJSON(products);
});
}
@get
hello(context) {
// HTTP response will contain an 'X-RANDOM-NUMBER' header
context.send('Hello');
}
}
function addRandomHeader(context) {
context.setHeader('X-RANDOM-NUMBER', Math.random().toString());
context.next();
}
Connect/Express middleware support
Connect/Express middlewares are supported via the use
helper function.
The use
function transforms a middleware to a before interceptor.
import { before, controller, get, use } from 'kikwit';
@before(use(requestStamp))
@controller
export class Products {
@get
list(context) {
// context.request.stamp is set
context.send('List');
}
@get
details(context) {
// context.request.stamp is set
context.send('Details');
}
}
function requestStamp(req, res, next) {
req.stamp = Date.now();
next();
};
Please always use the Context
helper methods when possible and avoid accessing the underlying request and response objects directly.