NodeJS | How to upload to AWS S3 using Express and Multer (3)

bubblegum·2024년 2월 12일

NodeJS

목록 보기
14/14
post-thumbnail
// s3Service.js

const {s3} = require("aws-sdk");
const {s3client, PutObjectCommand} = require("@aws-sdk/client-s3")
const uuid = require("uuid").v4;

exports.s3UploadV2 = async(files) => {
  const s3 = new s3();
  
  // const param = {
  //   Bucket: process.env.AWS_BUCKET_NAME,
  //   Key: `uploads/${uuid()}-${file.originalname}`,
  //   Body: file.buffer
  // };
  
  const params = files.map(file => {
    return {
      Bucket: process.env.AWS_BUCKET_NAME,
      Key: `uploads/${uuid()}-${files.originalname}`,
      Body: files.buffer
    }
  })

  return await Promise.all(
    params.map(param => s3.upload(param).promise())
  );

}

exports. s3UploadV3 = async (files) => {
  const s3client = new s3client();

  const param = {
    Bucket: process.env.AWS_BUCKET_NAME,
    Key: `uploads/${uuid()}-${files.originalname}`,
    Body: files.buffer
  }

  return await Promise.all(
    params.map(param => s3client.send(new PutObjectCommand(param)))
  )
  
}
// index.js

require("dotenv").config();
const express = require("express");
const multer = require("multer");
const {s3UploadV2, s3UploadV3} = require("./s3Service");
const uuid = require("uuid").v4; 

const app = express(); 

// custom filename
const storage = multer.memoryStorage({
  destination: (req, file, cb) => { // cb의 첫 번째 인수: 에러가 발생했을 때 반환하는 값, 두번째 인수: 에러가 발생하지 않았을 때 실제 경로나 파일 이름
    cb(null, "uploads");
  },
  filename: (req, file, cb) => {
    const {originalname} = file;
    cb(null, `${uuid()}-${originalname}`);
  }
});

const fileFilter = (req, file, cb) => {
  if(file.mimetype.split("/")[0] === 'image/jpeg') {
    cb(null, true)
  } else {
    cb(new Error("file is not of the correct type."), false);
  }
}; 

const upload = multer({
  storage, 
  fileFilter, 
  limits: {fileSize: 1000000, files: 2}
});//1 megabyte

// app.post("/upload", upload.array("file"), async (req, res) => {
//   try {
//     const file = req.files[0];
//     const results = await s3UploadV2(file);
//     res.status(200).json({success: true, results}); 
//   } catch (error) {
//     console.log(error)
//   }
// })

app.post("/upload", upload.array("file"), async (req, res) => {

  try {
    const results = await s3UploadV3(req.files);
    res.status(200).json({success: true, results}); 
  } catch (error) {
    console.log(error)
  }
})

// error handling middleware
app.use((error, req, res, next)=>{
  if (error instanceof multer.MulterError) {
    if(error.code==="LIMIT_FILE_SIZE") {
      return res.json({message: "file limit reached."});
    }
    
    if(error.code === "LIMIT_FILE_COUNT"){
      return res.json({message: "file is too large."});
    }
    
    if(error.code === "LIMIT_UNEXPECTED_FILE"){
      return res.json({message: "file must be an image."});
    }
  }
})

app.listen(4000, () => console.log("listening on port 4000"));
profile
황세민

0개의 댓글