Reputation: 5235
I would like to make my route Query
parameter required.
If it is missing I expect it to throw 404 HTTP error.
@Controller('')
export class AppController {
constructor() {}
@Get('/businessdata/messages')
public async getAllMessages(
@Query('startDate', ValidateDate) startDate: string,
@Query('endDate', ValidateDate) endDate: string,
): Promise<string> {
...
}
}
I'm using NestJs pipes to determine if a parameter is valid, but not if it exists And I'm not sure that Pipes are made for that.
So how can I check in NestJS if my param exists if not throw an error?
Upvotes: 15
Views: 35164
Reputation: 851
You can define a DTO like you would for a @Body
, instead of listing all the query params in the function args, like so:
@Get('/businessdata/messages')
public async getAllMessages(
@Query() getAllMessagesDto: GetAllMessagesDto
): Promise<string> {
console.log(getAllMessagesDto.endDate) // etc
}
And define your DTO with your requirements like so:
import { IsNotEmpty } from 'class-validator';
export class GetAllMessagesDto {
@IsNotEmpty()
startDate: Date;
@IsNotEmpty()
endDate: Date;
}
You can check this doc to see details about how to add validators to your DTO, and in your case don't forget to add forbidNonWhitelisted
if you want to refuse values that are not expected.
Upvotes: 2
Reputation: 161
NestJS does not provide a decorator (like @Query
) that detects undefined
value in request.query[key]
.
You can write custom decorator for that:
import { createParamDecorator, ExecutionContext, BadRequestException } from '@nestjs/common'
export const QueryRequired = createParamDecorator(
(key: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest()
const value = request.query[key]
if (value === undefined) {
throw new BadRequestException(`Missing required query param: '${key}'`)
}
return value
}
)
Then use @QueryRequired
decorator as you would use @Query
:
@Get()
async someMethod(@QueryRequired('requiredParam') requiredParam: string): Promise<any> {
...
}
Upvotes: 14
Reputation: 123
In addition to Phi's answer, you can combine the use of class-validator
with the following global validation pipe:
app.useGlobalPipes(
new ValidationPipe({
/*
If set to true, instead of stripping non-whitelisted
properties validator will throw an exception.
*/
forbidNonWhitelisted: true,
/*
If set to true, validator will strip validated (returned)
object of any properties that do not use any validation decorators.
*/
whitelist: true,
}),
);
I use this in order to only allow parameters defined in the DTO class so that it will throw an error when unknown parameters are sent with the request!
In Phie's example, a post request with a body like {password: 'mypassword'}
will pass the validation when {password: 'mypassword', other: 'reject me!'}
won't.
Upvotes: 2
Reputation: 413
Use class-validator
. Pipes are definitely made for that !
Example : create-user.dto.ts
import { IsNotEmpty } from 'class-validator';
export class CreateUserDto {
@IsNotEmpty()
password: string;
}
For more information see class-validator
documentation :
https://github.com/typestack/class-validator
And NestJS Pipes & Validation documentation : https://docs.nestjs.com/pipes https://docs.nestjs.com/techniques/validation
Upvotes: 16
Reputation: 403
There hava a easy way to valide you parameter, https://docs.nestjs.com/techniques/validation
Upvotes: 4