Hooks
foal generate hook my-hook
Description
Hooks are decorators that execute extra logic before and/or after the execution of a controller method.
They are particulary useful in these scenarios:
- authentication & access control
- request validation & sanitization
- logging
They improve code readability and make unit testing easier.
Built-in Hooks
Foal provides a number of hooks to handle the most common scenarios.
ValidateBody
,ValidateHeader
,ValidatePathParam
,ValidateCookie
andValidateQueryParam
validate the format of the incoming HTTP requests (see Validation).Log
displays information on the request (see Logging).JWTRequired
,JWTOptional
,UseSessions
authenticate the user by filling thectx.user
property.PermissionRequired
restricts the route access to certain users.
Use
A hook can decorate a controller method or the controller itself. If it decorates the controller then it applies to all its methods and sub-controllers.
In the below example, JWTRequired
applies to listProducts
and addProduct
.
Example:
import {
Context, Get, HttpResponseCreated, HttpResponseOK, Post, ValidateBody
} from '@foal/core';
import { JWTRequired } from '@foal/jwt';
@JWTRequired()
class AppController {
private products = [
{ name: 'Hoover' }
];
@Get('/products')
listProducts() {
return new HttpResponseOK(this.products);
}
@Post('/products')
@ValidateBody({
additionalProperties: false,
properties: {
name: { type: 'string' }
},
required: [ 'name' ],
type: 'object',
})
addProduct(ctx: Context) {
this.products.push(ctx.request.body);
return new HttpResponseCreated();
}
}
If the user makes a POST request to /products
whereas she/he is not authenticated, then the server will respond with a 400 error and the ValidateBody
hook and addProduct
method won't be executed.
If you need to apply a hook globally, you just have to make it decorate the root controller:
AppController
.@Log('Request body:', { body: true })
export class AppController {
// ...
}