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 RoutesFW24 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 DecoratorFor 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}); } }
Validations()
Decorator#
Implementing Validation in the 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}); }}