Dandy Now!
  • [NestJS] Postman에서 이미지 업로드 테스트, 왜 400?!
    2023년 11월 02일 17시 00분 01초에 업로드 된 글입니다.
    작성자: DandyNow
    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 파일이 성공적으로 업로드되었다.

    [그림 1] Key를 올바르게 넣고 테스트한 결과이다. 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
    반응형
    댓글