[2024.06.05 TIL] 내일배움캠프 36일차 (팀프로젝트 구현, Multer, AWS S3, 챌린지반, 슬랙 톺아보기)

My_Code·2024년 6월 6일
0

TIL

목록 보기
47/112
post-thumbnail

본 내용은 내일배움캠프에서 활동한 내용을 기록한 글입니다.


💻 TIL(Today I Learned)

📌 Today I Done

✏️ 챌린지반 특강 - 슬랙 톺아보기

  • 허들 기능
    • 슬랙에서 제공하는 오디오 및 비디오 컨퍼런스 기능
    • WebRTC (Web Real-Time Communication) 기술을 활용함
    • WebRTC는 P2P(Peer to Peer) 연결을 통해 실시간으로 소통하게 하는 기술임
    • P2P(Peer to Peer)의 문제는 1:1 통신은 아주 좋지만 1:N의 통신은 큰 부담이 될 수 있음

  • 음성 메세지 전송
    • 음성 녹음 => Web Audio API 활용
    • 파일 업로드 => multer 미들웨어 활용
    • 파일 서빙 => AWS S3에서 파일에 대한 URL를 제공

  • 동영상 클립 전송
    • 동영상은 용량이 크기 때문에 직접 S3 같은 곳에 저장하지 못함
    • 파일 업로드 및 저장 => 트랜스코딩 된 결과물을 버킷에 저장
    • 트랜스코딩으로 파일의 크기를 줄여야 함

  • 멘션 기능
    • @ 라는 특수 문자로 특정 누군가를 언급하여 메시지 전송
    • 자동 완성 기능에 전달되는 입력값 정규화
      • Throttle 기법과 Debounce 기법에 대해서도 공부해보기
    • Trie(트라이)라는 자료구조를 사용해서 추천 목록 출력
      • 트라이는 문자열 탐색을 위해 태어난 자료구조
    • 서버는 멘션 대상자에게 해당 채팅 메시지에 대한 알림을 전송

✏️ AWS S3를 이용한 Multer 구현

  • AWS S3란?

    • AWS에서 제공하는 파일 저장 서버
    • 이미지나 동영상은 크기가 크기 때문에 직접 DB에 넣으면 너무 비효율적임
    • 그렇기에 실제 파일은 S3에 저장하고 그에 연결된 URL를 반환해줌
    • 그 URL를 DB에 저장하는 방식
  • Multer, Multer-s3 라이브러리를 이용해서 이미지를 업로드

  • 아래 코드는 S3에 접근하기 위한 기본적인 값

import multer from 'multer';
import multerS3 from 'multer-s3';
import path from 'path';
import aws from '@aws-sdk/client-s3';

const s3 = new aws.S3({
  region: process.env.AWS_S3_REGION,
  credentials: {
    accessKeyId: process.env.AWS_S3_ACCESS_KEY,
    secretAccessKey: process.env.AWS_S3_SECRET_KEY,
  },
});
  • https://velog.io/@bbaekddo/aws-s3

  • Multer-s3에는 S3에 접근하기 위한 옵션부터 권한 설정, 용량 제한 등 다양한 설정이 가능

  • 하지만 확장자를 검사하는 과정은 따로 필요함

  • 그래도 다행히 path 라이브러리를 통해 확장자를 분리할 수 있기 때문에 includes 메서드로 비교하면 됨

// 허용 가능한 확장자 배열
const allowedExtensions = ['.png', '.jpg', '.jpeg', '.bmp', '.gif'];

// multer 객체 생성
export const uploadImage = multer({
  storage: multerS3({
    s3: s3,
    bucket: process.env.AWS_BUCKET,
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: (req, file, callback) => {
      const userId = req.user.id;

      // 오늘 날짜 구하기
      const today = new Date();
      const currentYear = today.getFullYear();
      const currentMonth = today.getMonth() + 1;
      const currentDate = today.getDate();
      const date = `${currentYear}-${currentMonth}-${currentDate}`;

      // 임의번호 생성
      let randomNumber = '';
      for (let i = 0; i < 8; i++) {
        randomNumber += String(Math.floor(Math.random() * 10));
      }

      // 확장자 검사
      const extension = path.extname(file.originalname).toLowerCase();
      if (!allowedExtensions.includes(extension)) {
        return callback(new Error('확장자 에러'));
      }

      // folder라는 파일 내부에 업로드한 사용자에 따라 임의의 파일명으로 저장
      callback(null, `test/${userId}_${date}_${randomNumber}`);
    },
    // acl 권한 설정
    acl: 'public-read-write',
  }),
  // 이미지 용량 제한 (5MB)
  limits: {
    fileSize: 5 * 1024 * 1024,
  },
});
  • 실제로 위의 Multer를 적용하기 위해서는 사용할 라우터의 미들웨어로 넣으면 됨

  • multer.single(폼에 정의된 필드명)

    • 한 번의 요청으로 하나의 파일만 업로드할 때 사용
    const multer  = require('multer');
    const upload = multer({ dest: 'uploads/' });
    
    app.post('/upload', upload.single('photo'), (req, res) => {
      // 'photo' 필드명으로 하나의 파일을 업로드
      res.send('File uploaded!');
    });
  • multer.array(폼에 정의된 필드명, 최대 파일 수)

    • 하나의 필드에 대해 여러 파일을 업로드할 때 사용
    const multer  = require('multer');
    const upload = multer({ dest: 'uploads/' });
    
    app.post('/upload', upload.array('photos', 12), (req, res, next) => {
    	// 'photos' 필드에 최대 12개의 파일을 업로드
    	res.send('Files uploaded!');
    });
  • multer.fields(폼에 정의된 필드명, 최대 파일 수)

    • 여러 필드에 대해 각각 여러 파일을 업로드할 때 사용

      const multer  = require('multer');
      const upload = multer({ dest: 'uploads/' });
      
      app.post('/upload', upload.fields([{ name: 'photos', maxCount: 8 },{ name: 'documents', maxCount: 2 }]), (req, res, next) => {
        // 'photos' 필드에 최대 8개의 파일, 'documents' 필드에 최대 2개의 파일을 업로드
        res.send('Files uploaded!');
      });


📌 Tomorrow's Goal

✏️ 팀프로젝트 과제 마무리하기

  • 팀프로젝트 과제 발표 준비하기

  • API 명세서, ERD, Readme 문서들 최신화 하기

  • 각 API 테스트 진행하기

  • 시간적 여유가 된다면 백엔드 개발 추가로 진행하기



📌 Today's Goal I Done

✔️ 팀프로젝트 기능 구현하기

  • 오늘을 기준으로 대부분의 기능들이 완성되었기 때문에 명예의 전당을 도전함

  • 그 중에서도 S3를 사용한 Multer 이미지 업로더를 만드는 것을 진행함

  • 다행히 튜터님의 블로그를 참고하니 생각보다 쉽게 적용이 가능했음

  • 다만 multer를 미들웨어로 적용할 때 유효성 검사보다 먼저 실행되어야 함



⚠️ 구현 시 발생한 문제

✔️ CredentialsProviderError: Could not load credentials from any providers

// v2

import multer from 'multer';
import multerS3 from 'multer-s3';
import path from 'path';
import aws from '@aws-sdk/client-s3';

const s3 = new aws.S3({
  region: process.env.AWS_S3_REGION,
  accessKeyId: process.env.AWS_S3_ACCESS_KEY,
  secretAccessKey: process.env.AWS_S3_SECRET_KEY,
});
// v3

import multer from 'multer';
import multerS3 from 'multer-s3';
import path from 'path';
import aws from '@aws-sdk/client-s3';

const s3 = new aws.S3({
  region: process.env.AWS_S3_REGION,
  credentials: {
    accessKeyId: process.env.AWS_S3_ACCESS_KEY,
    secretAccessKey: process.env.AWS_S3_SECRET_KEY,
  },
});
profile
조금씩 정리하자!!!

0개의 댓글