반응형

express사용 환경에서 multer를 사용해서 S3에 이미지를 저장해야 하는 상황이 생겼다.

이 글에서는 이미지를 받아서 서버 폴더에 저장하는 방법에 대해 서술한다.

 

환경

express: 4.x

multer: 1.4.5-lts

 

필요한 패키지 설치

  • multer를 설치한다.
npm i multer
  • typescript 환경인 경우 타입 추가로 설치한다.
npm i @types/multer
  • aws-sdk를 설치한다.
npm i aws-sdk

 

라우터 생성

이미지를 받기위한 라우터를 생성한다. 전체 코드는 아래와 같다.

const upload = multer({ dest: path.join(__dirname, 'uploads/') });
app.get('/test',upload.array('images', 5), async (req, res, next) => {
    const test = req.files ?? [];
    await utilClass.uploadImageToS3(test);
    res.send('OK')
});
  • multer를 사용해 upload 객체를 생성하고 업로드된 파일을 임시로 저장할 공간을 지정한다.
const upload = multer({ dest: path.join(__dirname, 'uploads/') });
  • 이미지 업로드를 할때 images라는 이름으로 받고 최대 5개까지만 받는다.
upload.array('images', 5)
  • 업로드된 파일들은 req.files로 라우터에서 사용할 수 있다. 이 때 파일을 업로드하지 않으면 req.files가 undefined가 되기 때문에 이를 막기위해 null 병합 연산자를 사용해 빈 배열로 만들어준다.
const test = req.files ?? [];
  • s3에 업로드한다.
await uploadImageToS3(test);

 

s3 업로드 로직 구현

aws-sdk를 사용해서 S3 버킷에 이미지를 업로드 한다. 전체 코드는 아래와 같다.

  async uploadImageToS3(images) {
      const s3 = new S3({
          accessKeyId: 'AWS 엑세스 키',
          secretAccessKey: 'AWS 시크릿 키',
          region: '버킷이 있는 지역',
      });

      const promiseList = images.map((file) => {
          const fileStream = fs.createReadStream(file.path);

          return s3.upload({
                  Bucket: '버킷이름',
                  // 파일명
                  Key: `uploads/${file.originalname}`,
                  Body: fileStream,
              })
              .promise();
      });

      const result = await Promise.all(promiseList);

      for (let i = 0; i < files.length; i++) {
          fs.unlink(files[i].path, (err) => {
              if (err) throw err;
          });
      }

      return result;
  }
}
  • s3 객체를 생성한다.
    • S3 객체 생성시 config에 대해서는 아래 링크를 참조하자.
 

[Node.js] node.js에서 object를 s3에 올리는 방법

작업 중 node.js 환경에서 요청으로 받은 object 자체를 json으로 변환해서 s3에 올려야 하는 일이 생겼다. 해당 글에서는 node.js에서 s3로 업로드 하는 방법과 IAM 설정 방법에 대해 서술한다. 환경 node.j

systorage.tistory.com

const s3 = new S3({
          accessKeyId: 'AWS 엑세스 키',
          secretAccessKey: 'AWS 시크릿 키',
          region: '버킷이 있는 지역',
      });
  • s3로 업로드 하는 프로미스 객체들을 promiseList 안에 배열로 저장한다.
    • fs를 사용해서 이미지의 임시 파일을 스트림 형식으로 생성한다.
    const promiseList = images.map((file) => {
              const fileStream = fs.createReadStream(file.path);
    
              return s3.upload({
                      Bucket: '버킷이름',
                      // 파일명
                      Key: `uploads/${file.originalname}`,
                      Body: fileStream,
                  })
                  .promise();
          });
    
  • promiseList에 담아두었던 프로미스 객체들을 Promise.all을 사용해서 병렬로 처리한다.
const result = await Promise.all(promiseList);
  • for문을 사용해서 서버에 임시적으로 저장해두었던 파일들을 비동기적으로 삭제한다.
for (let i = 0; i < files.length; i++) {
	fs.unlink(files[i].path, (err) => { if (err) throw err; }); 
}

이렇게 multer를 사용해서 서버로 이미지를 업로드하고 그 이미지를 S3에 저장할 수 있다.

반응형
얼은펭귄