<MongoDB> multer

김민석·2021년 1월 8일
0

YouTube clone

목록 보기
27/54

middleware를 통해 중간에 upload하려는 파일을 가지고 올 수 있다는 얘기를 했던게 기억이 나시나요? 기억이 나지 않더라도 오늘 다시 되새기며 공부해보겠습니다.

multer

multer란?

multer는 파일 저장을 위해 사용되는 node.js middleware입니다. multer를 이용해서 파일을 저장하면 파일명이 임의로 바뀌고 문서형태로 변환되게 됩니다.
multer를 사용하기 위해선 form의 속성인 enctype(인코딩 타입)이 multipart/form-data 이어야 합니다. enctype이 지정되어 있지 않으면 저장할 수 없으니 유의합니다.
<form enctype="multipart/form-data">

설치

%npm install multer를 터미널에 입력

project

youtube
  |views
   *|upload.pug
 *|middlewares.js
  |routers
   *|videoRouter.js
    

upload.pug

video file을 upload하라고 form을 만들어 두었는데 image 파일을 올리면 안되겠죠? upload 가능한 파일 확장자에 대한 제한을 위해서는 input의 accept property를 사용합니다.
<input type="file" accept="파일 확장자|audio/*|video/*|image/*|미디어 타입">와 같은 형식을 사용하면 됩니다.
우리는 video를 원하기 때문에 <input type="file" accept="video/*">라고 하겠습니다.

block content
  form(action=routes.upload, method="post", enctype="multipart/form-data")
    input(type="file", accept="video/*");
	//나머지 생략

middlewares.js

middleware로 사용하기 위해서 configuration이 필요하므로 middlewares 파일에서 선언하고 설정을 해주도록 하겠습니다.

  1. 파일이 저장될 위치를 알려주어야합니다.
  • videos/로 저장 디렉토리를 지정해줬으므로 프로젝트 폴더에 videos 폴더를 하나 만들어야합니다. videos/라는 뜻은 현재 폴더 밑에 videos라고 생각하면 됩니다. /videos/로 하면 컴퓨터 루트폴더로부터의 폴더경로를 의미하게 되므로 주의합니다. (폴더는 multer가 자동으로 생성하므로 신경쓰지 않아도 됩니다.)
  1. 어떤 이름의(form에서 name 속성) 파일을 몇개 업로드 할지도 정해야합니다.
  • 이름은 form내부 file type input의 name과 동일해야 합니다.
  • single의 의미는 하나의 파일을 업로드한다는 뜻입니다.
import multer from 'multer';

const uploadVideo = multer({dest:'videos/'});
export const uploadVideoMiddleware = uploadVideo.single('videoFile');
/*다른 middleware 생략*/

videoRouter.js

post method로 /upload로 요청하면 응답으로 postUpload가 실행되는데요. postUpload가 실행되기전에 파일을 업로드하기위해 uploadVideoMiddleware를 사이에 넣어줍니다. 그러면 이 middleware가 저장한 파일에 대한 정보를 req.file에 넣은 후 postUpload를 실행시킵니다. 참고로 middleware끼리는 res,req를 공유합니다.

import {uploadVideoMiddleware}  from '../middlewares';

/*생략*/
videoRouter.post(routes.upload, uploadVideoMiddleware, postUpload);

videoController

이제 마지막으로 postUpload 함수에 대한 코드를 살펴보겠습니다. multer는 저장한 파일에 대한 정보를 req의 file에 담아서 보냅니다. 아래의 코드로 우리는 file을 받을 수 있습니다.

export const postUpload = async(req, res) => {
  const {file} = req;
  console.log(file);
}

upload 페이지에서 업로드를 하고 콘솔을 확인하면 아래와 같습니다.

업로드한 file에 대한 정보를 볼 수 있네요. 이 중에서 눈여겨볼 것은 바로 path 입니다. 우리가 Video Model을 만들때 우리는 database에 file 자체를 저장하는 것이 아니라 fileURL을 저장할 것이라고 하였죠. 이 fileURL에 해당하는 것이 바로 path입니다. 이제 이 정보를 이용하여 데이터베이스에 Video element를 추가해보겠습니다.

  • Video.create({})
    Video model의 메소드 create에 하여 element 객체를 전달하여 실행하면 해당 element를 데이터베이스에 저장하고 저장된 video 객체를 반환해줍니다.
  • newVideo.id
    redirect하는 부분을 보면 우리는 Video model schema로 id를 적어준적은 없지만 mongoDB 자체적으로 id를 부여하기 때문에 id 속성을 사용할 수 있습니다._id로 하여도 동일합니다.
import Video from '../models/Video';

export const postUpload = async(req, res) => {
  const {body:{title, description}, file:{path}} = req;
  const newVideo = await Video.create({
    fileUrl: path,
    title,
    description
  });
  res.redirect(routes.videoDetail(newVideo.id));
}
profile
누구나 실수 할 수 있다고 생각합니다. 다만 저는 같은 실수를 반복하는 사람이 되고 싶지 않습니다. 같은 실수를 반복하지 않기 위해 기록하여 기억합니다.🙃

0개의 댓글