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});
}
}