19

My controller code is something like this.

@Controller('customer')
export class CustomerController{

    constructor(private readonly customerService: CustomerService){}

    @Post('lookup')
    async someMethod(@Body() body:any){

        console.log("BEGIN -- CustomerController.someMethod");

I am expecting to see in Swagger a place where I can input some text as a request body but instead I see this

enter image description here

p0tta
  • 1,461
  • 6
  • 28
  • 49

6 Answers6

20

Add @ApiProperty()

export class User{

 @ApiProperty()
  name:string
 
}
9

So it sounds like there's a few things going on here. The Swagger UI is a helper tool for sending in requests, but to do that it needs to know the shape of the request body. any is not good enough. If you're looking for a tool that allows you to send in anything, curl or postman are you best bets (at least for free).

Nest has a Swagger plugin that will read through your Typescript code and decorate your types and method accordingly, but you have to opt in to enable it. Otherwise, you need to use the decorators from the @nestjs/swagger package to tell Swagger what types are expected in and out of the methods.

So long as the type that corresponds to @Body() has swagger decorators or you enable the swagger plugin and have a valid class, the swagger UI should show up as expected, but with the above and using type any it won't do you any good.

Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147
  • Do I need to install the Swagger plugin or does it come out of the box if I have this in my package.json? "@nestjs/swagger": "^4.4.0" – p0tta May 28 '20 at 04:13
  • 1
    The link to the docs in my answer clearly explains how to set up the plugin to work. – Jay McDoniel May 28 '20 at 05:30
  • 2
    I tried with setting body type to an interface, still it did not work. Finally, replacing the interface as class worked. Thanks... – shanti Mar 09 '21 at 05:10
  • 1
    Interfaces don't exist at runtime, so there's no metadata to reflect about them. – Jay McDoniel Mar 09 '21 at 16:10
2

My endpoint accepts unknown key/value data and I was having the same problem (I tried any, unknown, Record<string, any>, object, {}). Finally @Body() data: Map<string, any> worked for me.

Marco C.
  • 1,282
  • 2
  • 15
  • 19
2

try it like this:

@ApiBody({description: "body:any someMethod"})
@Post('lookup')
async someMethod(@Body() body:any){
console.log("BEGIN -- CustomerController.someMethod");
}
Kir SR
  • 39
  • 2
1

I would recommend using dto for body.

Refer to documentation.

Example of a DTO is shown below.

DTO:

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}

Function

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  //Do Stuff.
}

@ApiProperty adds properties to swagger request.

It should show something like this: enter image description here

@Post()
@ApiBody({ type: CreateCatDto })
async create(@Body() createCatDto: CreateCatDto) {
  //Do Stuff.
}

The above code is going to give output similar to below where your schema is also going to be documented:

enter image description here

Hope this helps.

Sohail Shrestha
  • 477
  • 5
  • 6
0

Create a file with *.dto.ts and add the below code in nest-cli.json unser compilerOptions. You do not need to add @ApiProperty on each field

"plugins": [
  {
    "name": "@nestjs/swagger",
    "options": {
      "introspectComments": true
    }
  }
]
Pramod Patil
  • 2,704
  • 2
  • 14
  • 20