Skip to main content

Validating Requests

FW24 boasts a robust validation framework, offering two types of validation for API endpoints:

  • InputValidationRule<{...some-type...}> allows for straightforward validations for any input or type.

        const myInputValidation: InputValidationRule<{a: string, b: string}> = {        a: {            required: true,            minLength: 5        },        b: {            required: true,            dataType: 'email'        }    }
  • HttpRequestValidations offers validation rules for the entire HTTP request, including the body, header, param, and query.

        type Body = {        a: string,        b: string,    };
        type Param = {        id: string,    };
        type Header = {        'xxx-api-key': string,        'xxx-client-id': string,    };
        type Query = {        cursor: string,        sort: 'asc' | 'desc',    };
        const myHttpRequestValidations: HttpRequestValidations<Header, Body, Param, Query> = {        body: {            a: {                required: true,                maxLength: 100,            },            b: {                required: true,                inList: ['My Auth 1', 'My Auth 2'] // The author must be one of the two names            }        },        path: {            id: {                required: true,                dataType: 'uuid',            }        },        query: {            cursor: {                required: true,            },            sort: {                inList: ['asc', 'desc']            }        },        header: {            'xxx-api-key': {                eq: 'xxx-yyy-zzz'            },            'client-id': {                required: true            }        }    }

Implementing Validations for Routes#

FW24 supports the addition of validation in method decorators and also offers a dedicated @Validations() decorator for those who prefer this approach..

Implementing Validation in the Method Decorator#

For methods of type [POST, PATCH, PUT], the validations apply to the request body. For other types, they apply to the query parameters.


    type RequestInputSchema = {        bookName: string,        authorName: string,    };
    @Controller('demo')    export class MyController extends APIController {                @Get('/my-endpoint', {            validations: {                bookName: {                    required: true,                    maxLength: 100,                },                authorName: {                    required: true,                    inList: ['My Auth 1', 'My Auth 2'] // The author must be one of the two names                }            }        })        private myEndpointHandler(req: Request, res: Response): Promise<Response>{            const {bookName, authorName} = req.queryString as RequestInputSchema;            return res.json({bookName, authorName});        }
        @Post('/my-endpoint', {            validations: {                bookName: {                    required: true,                    maxLength: 100,                },                authorName: {                    required: true,                    inList: ['My Auth 1', 'My Auth 2'] // The author must be one of the two names                }            }        })        private myEndpointHandler(req: Request, res: Response): Promise<Response>{            const {bookName, authorName} = req.body as RequestInputSchema;            return res.json({bookName, authorName});        }    }

Implementing Validation in the Validations() Decorator#

The @Validations() decorator supersedes the validations defined in the Method decorator. If the validations are of type InputValidation and the request method is one of [POST, PATCH, PUT], the validations apply to the request-body. Otherwise, they apply to the request-query-params.

{
    type RequestInputSchema = {        bookName: string,        authorName: string,    };
    // Validate the input. For POST, PATCH, and PUT, it's the body; otherwise, it's the query parameters.    @Validations({        bookName: {            required: true,            maxLength: 100,        },        authorName: {            required: true,            inList: ['My Auth 1', 'My Auth 2'] // Author can have only one of the 2 names        }    })    @Post('/another-endpoint')    private anotherHandler(req: Request, res: Response): Promise<Response>{
        const { bookName, authorName } = req.body as RequestInputSchema;
        return res.json({ bookName, authorName });    }
    @Validations(myHttpRequestValidations)    @Post('/awesome-endpoint/{id}')    private awesomeHandler(req: Request, res: Response): Promise<Response>{
        const { a, b } = req.body as RequestInputSchema;        const { id } = req.path as any;        const { cursor, sort } = req.query as any;
        return res.json({a, b, id, cursor, sort});    }}