-
-
Save alexwhin/ed13f34d0bae0449ddd9fb7e82cfeacd to your computer and use it in GitHub Desktop.
import { diskStorage } from "multer"; | |
import { FileInterceptor } from "@nestjs/platform-express"; | |
import { ApiResponse, ApiConsumes, ApiBody } from "@nestjs/swagger"; | |
import { | |
Res, | |
Get, | |
Post, | |
Param, | |
Controller, | |
UploadedFile, | |
UseInterceptors, | |
} from "@nestjs/common"; | |
@Controller("image") | |
export class ImageController { | |
@Get(":name") | |
@ApiResponse({ type: Buffer }) | |
async serveAvatar(@Param("name") name, @Res() response): Promise<any> { | |
response.sendFile(name); | |
} | |
@Post() | |
@UseInterceptors( | |
FileInterceptor("file", { | |
storage: diskStorage({ | |
filename: (_request, file, callback) => | |
callback(null, `${new Date().getTime()}-${file.originalname}`), | |
}), | |
}), | |
) | |
@ApiBody({ | |
required: true, | |
type: "multipart/form-data", | |
schema: { | |
type: "object", | |
properties: { | |
file: { | |
type: "string", | |
format: "binary", | |
}, | |
}, | |
}, | |
}) | |
@ApiConsumes("multipart/form-data") | |
async post(@UploadedFile() file): Promise<void> { | |
console.log(file); | |
} | |
} |
What if you got a dto and a file upload in the same endpoint?
What if you got a dto and a file upload in the same endpoint?
@blobmold I haven't tested but you could do something similar to this perhaps;
class CreateImageDto {
@IsString()
description: string;
}
...
@ApiBody({
description: "Image upload",
type: "multipart/form-data",
schema: {
type: "object",
properties: {
description: { type: "string" },
file: {
type: "string",
format: "binary",
},
},
},
})
@ApiConsumes("multipart/form-data")
async post(@UploadedFile() file, @Body() createImageDto: CreateImageDto): Promise<void> {
console.log(file, createImageDto);
}
@alexwhin What this would do is @ApiBody()
will override the @ApiProperty()
decorators in the dto, if you have it, of course.
@alexwhin What this would do is
@ApiBody()
will override the@ApiProperty()
decorators in the dto, if you have it, of course.
I think you're right yes, perhaps this then:
export class CreateImageDto {
@ApiProperty({
description: 'Description of the image',
type: String,
})
@IsString()
description: string;
}
...
@ApiConsumes('multipart/form-data')
@ApiBody({
description: 'Image upload',
type: CreateImageDto,
})
async post(@UploadedFile() file, @Body() createImageDto: CreateImageDto): Promise<void> {
console.log(file, createImageDto);
}
@alexwhin What this would do is
@ApiBody()
will override the@ApiProperty()
decorators in the dto, if you have it, of course.I think you're right yes, perhaps this then:
export class CreateImageDto { @ApiProperty({ description: 'Description of the image', type: String, }) @IsString() description: string; }... @ApiConsumes('multipart/form-data') @ApiBody({ description: 'Image upload', type: CreateImageDto, }) async post(@UploadedFile() file, @Body() createImageDto: CreateImageDto): Promise<void> { console.log(file, createImageDto); }
This is more like it I think. just need to add an image type to the @ApiBody()
I think.
@alexwhin What this would do is
@ApiBody()
will override the@ApiProperty()
decorators in the dto, if you have it, of course.I think you're right yes, perhaps this then:
export class CreateImageDto { @ApiProperty({ description: 'Description of the image', type: String, }) @IsString() description: string; }... @ApiConsumes('multipart/form-data') @ApiBody({ description: 'Image upload', type: CreateImageDto, }) async post(@UploadedFile() file, @Body() createImageDto: CreateImageDto): Promise<void> { console.log(file, createImageDto); }This is more like it I think. just need to add an image type to the
@ApiBody()
I think.
Good spot, so this may be the solution here:
export class CreateImageDto {
@ApiProperty({
description: 'Description of the image',
type: String,
})
@IsString()
description: string;
@ApiProperty({
description: 'Image file',
type: 'string',
format: 'binary',
})
file: any;
}
...
@Post()
@ApiConsumes('multipart/form-data')
@ApiBody({
description: 'Image upload',
schema: {
type: 'object',
properties: {
file: {
type: 'string',
format: 'binary',
},
description: {
type: 'string',
},
},
},
})
@UseInterceptors(FileInterceptor('file'))
async post(
@UploadedFile() file: Express.Multer.File,
@Body() createImageDto: CreateImageDto,
): Promise<void> {
console.log(file, createImageDto);
}
}
@alexwhin What this would do is
@ApiBody()
will override the@ApiProperty()
decorators in the dto, if you have it, of course.I think you're right yes, perhaps this then:
export class CreateImageDto { @ApiProperty({ description: 'Description of the image', type: String, }) @IsString() description: string; }... @ApiConsumes('multipart/form-data') @ApiBody({ description: 'Image upload', type: CreateImageDto, }) async post(@UploadedFile() file, @Body() createImageDto: CreateImageDto): Promise<void> { console.log(file, createImageDto); }This is more like it I think. just need to add an image type to the
@ApiBody()
I think.Good spot, so this may be the solution here:
export class CreateImageDto { @ApiProperty({ description: 'Description of the image', type: String, }) @IsString() description: string; @ApiProperty({ description: 'Image file', type: 'string', format: 'binary', }) file: any; }... @Post() @ApiConsumes('multipart/form-data') @ApiBody({ description: 'Image upload', schema: { type: 'object', properties: { file: { type: 'string', format: 'binary', }, description: { type: 'string', }, }, }, }) @UseInterceptors(FileInterceptor('file')) async post( @UploadedFile() file: Express.Multer.File, @Body() createImageDto: CreateImageDto, ): Promise<void> { console.log(file, createImageDto); } }
or smth like this
export class CreateDto {
@ApiProperty({
description: 'Description of the image',
type: String,
})
@IsString()
description: string;
}
export class CreateDtoWithImage extends CreateDto {
@ApiProperty({
description: 'Image file',
type: 'string',
format: 'binary',
})
@IsNotEmpty()
image: Express.Multer.File;
}
and then
@Post()
@ApiConsumes('multipart/form-data')
@ApiBody({
type: CreateDtoWithImage
})
@UseInterceptors(FileInterceptor('file'))
async post(
@UploadedFile() file: Express.Multer.File,
@Body() dto: CreateDto,
): Promise<void> {
console.log(file, dto);
}
}
this way you don't have the file in the dto, but swagger knows about it
Thanks man! was searching how to implement upload in swagger for hours.