언어·프레임워크/NestJS
[NestJS] Postman에서 이미지 업로드 테스트, 왜 400?!
DandyNow
2023. 11. 2. 17:00
728x90
반응형
1. 왜 400 에러가 오는 거지?!
REST Client(VSCODE의 extension, 스크립트를 작성하여 API를 테스트할 수 있다.)를 이용해서 파일 업로드 API를 테스트하였다. 아래는 테스트를 진행한 file-upload.http 파일이며 정상적으로 잘 작동하였다.
### 사진 업로드
POST http://localhost:3000/file-upload
Content-Type: multipart/form-data; boundary=test-file-upload
--test-file-upload
Content-Disposition: form-data; name="file"; filename="test.jpg"
Content-Type: image/jpeg
< test.jpg
--test-file-upload--
Postman에서도 테스트를 진행해 보았는데, 이럴 수가?! 400 에러가 왔다!
{
"message": "Unexpected field",
"error": "Bad Request",
"statusCode": 400
}
2. Body form-data의 Key를 잘 못 넣었구나!
2.1. FileInterceptor()의 첫 번째 인수를 Key로 넣었어야!
문제는 FileInterceptor의 첫 번째 인수인 'file'을 Body form-data의 Key로 넣어야 하는데 엉뚱한 Key를 넣었기 때문에 발생한 에러였다. 아래 코드에서 주석으로 설명된 부분을 참고하자!
// app.controller.ts
import {
Controller,
Get,
Post,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { AppService } from './app.service';
import { FileInterceptor } from '@nestjs/platform-express';
import { multerOption } from './multer.option';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
// (생략)
@Post('file-upload')
@UseInterceptors(FileInterceptor('file', multerOption)) // FileInterceptor의 첫번째 인수인 'file'을 Body form-data의 Key로 넣어야 한다.
fileUpload(@UploadedFile() file: Express.Multer.File) {
console.log(file);
return `${file.filename}`;
}
}
올바른 키를 넣었더니 [그림 1]과 같이 jpg 파일이 성공적으로 업로드되었다.
2.2. 참고 : file-upload API 구현을 위해 함께 작성한 코드
// multer.option.ts
import { randomUUID } from 'crypto';
import { diskStorage } from 'multer';
import { extname, join } from 'path';
export const multerOption = {
storage: diskStorage({
destination: join(__dirname, '..', 'uploads'),
filename: (req, file, cb) => {
cb(null, randomUUID() + extname(file.originalname));
},
}),
};
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'uploads'),
serveRoot: '/uploads',
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
728x90
반응형