Reputation: 870
I am trying to create swagger documentation for a file upload API with NestJS.
This is what I currently have in my controller:
@ApiTags('files')
@Controller('files')
export class FilesController {
@ApiConsumes('multipart/form-data')
@ApiCreatedResponse({description: "This api creates a file in the system"})
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file, @Body() fileInfo: UploadFileDto) {
console.log(file);
console.log(fileInfo);
}
}
and in my DTO file:
import { IsString } from 'class-validator'
import { ApiProperty } from '@nestjs/swagger'
export class UploadFileDto {
@IsString()
communityName: string
@IsString()
type: string
@ApiProperty({type:"file"})
file: any;
}
This way, it shows everything in swagger (and works) properly. However, as you can see there is a redundant "file" variable in my DTO class and function variable. If I remove the "file" attribute from the DTO, then the swagger UI doesn't recognize this parameter as the file input. If I remove it from the function parameter, then it shows up in swagger UI but the controller doesn't receive the uploaded file. Is there a way to correct this?
Thanks.
Upvotes: 0
Views: 7356
Reputation: 63
I just encountered the same problem and thanks to you, I actually solved my issue.
My controller looks as following
@Controller('files')
@ApiTags('files')
export class FilesController
{
@Post('import')
@ApiConsumes("multipart/form-data")
@UseInterceptors(FileInterceptor('file',
{
storage: diskStorage({
destination: './tmp',
filename: (req, file, cb) => {
const randomName = Array(32).fill(null).map(() => (Math.round(Math.random() * 16)).toString(16)).join('')
return cb(null, `${randomName}${extname(file.originalname)}`)
}
})
}
))
async upload(
@Body() uploadDto: UploadDto,
@UploadedFile() file: Express.Multer.File
): Promise<void>
{
console.log(importDto);
console.log(file);
}
}
And my DTO
import { IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class ImportDto {
@IsString()
name: string;
@ApiProperty({ type:'string', format:'binary' })
file: any;
}
Notice the only real change is in the @ApiProperty()
in the DTO. That did the trick.
Upvotes: 2