How to write @Param and @Body in one DTO

Viewed 1057

I am using nestjs and I make an effort DTO's and I generate update-todo.dto.ts like this.

How can I use @Param and @Body together in one DTO?

@Param('id') id: string,
@Body('status') status: TodoStatus

So how to convert my code?

import { TodoStatus } from '../todo.model';
export class UpdateTodoDto {
  id: string;
  status: TodoStatus;
}
  @Patch('/:id/status')
  updateTodoStatus(
    @Param('id') id: string,
    @Body('status') status: TodoStatus
    // convert this line
  ): Todo {
    return this.todosService.updateTodoStatus(id, status);
  }
1 Answers

You'd need, four components to work together.

  1. A custom decorator to combine the @Param() and @Body() decorators
  2. A DTO to hold the shape of the @Param() DTO
  3. A DTO to hold the shape of the @Body() DTO
  4. A DTO to combine the body and param DTOs

This repository goes through an example with an optional body based on a query parameter.

1

export const BodyAndParam = createParamDecorator((data: unknwon, ctx: ExecutionContext) => {
  const req = ctx.switchToHttp().getRequest();
  return { body: req.body, params: req.params };
});

2

export class ParamsDTO {

  @IsString()
  id: string;
}

3

export class BodyDTO {
  @IsString()
  hello: string;
}

4

export class MixedDTO {
  @Type(() => ParamsDTO)
  params: ParamsDTO;
  
  @Type(() => BodyDTO);
  body: BodyDTO;
}

Use

@Controller()
export class FooController {
  @Post()
  bar(@BodyAndParam() bodyAndParam: MixedDTO) {
    // do stuff here
  }
}
Related