Creating a Video # 02

0_CyberLover_0·2022년 4월 10일
0

Node.JS # 03

목록 보기
10/19

전 단계에서 new video document를 만들었다.

videoController.js에서

export const postUpload = (req, res) => {
  const { title, description, hashtags } = req.body;
  const video = new Video({
    title: title,
    description: description,
    createdAt: Date.now(),
    hashtags: hashtags.split(",").map((word) => `#${word}`),
    meta: {
      views: 0,
      rating: 0,
    },
  });
  console.log(video);
  return res.redirect("/");
};

이렇게 만든건 javascript object였지만 아직 database에는 전송하지는 못하였다.

video에게는 string으로 구성된 title이 있다는 걸 기억 할 거다.

그런데 string이 아닌 number를 적으면 어떻게 될까?

export const postUpload = (req, res) => {
  const { title, description, hashtags } = req.body;
  const video = new Video({
    title: 5,
    description: description,
    createdAt: Date.now(),
    hashtags: hashtags.split(",").map((word) => `#${word}`),
    meta: {
      views: 0,
      rating: 0,
    },
  });
  console.log(video);
  return res.redirect("/");
};

숫자로 변경해 준 다음에 새로고침 이후 빈칸을 다시 채워 주고 upload를 해보았다.

✅ Server listening on port http://localhost:4000 🚀
✅Connected to DB
GET /videos/upload 200 177.062 ms - 754
{
  title: '5',
  description: 'adfgag',
  createdAt: 2022-04-10T09:02:11.998Z,
  hashtags: [ '#dsfgasgh', '#adfasga', '#asdfasf' ],
  meta: { views: 0, rating: 0 },
  _id: new ObjectId("62529d14c4f1874fa0d208ad")
}
POST /videos/upload 302 28.988 ms - 46
GET / 304 68.016 ms - -

에러가 나지 않고 title이 그냥 string으로 변환 되었다.

이말은 number 데이터를 넣어도 문제없이 string으로 변환 된다는 말이다.

보다시피 시스템이 도와주고 있는 거다. 이런 작은 도움 만으로도 보다 쾌적하게 코딩을 할수 있게 된다.

일단 이 코드는 원래 상태로 되돌려 놓는다.

그리고 viewsrating을 보면 number로 설정이 되어 있다.

이걸 반대로 string으로 해놓으면 어떻게 될까? 이것도 한번 시도해 본다.

터미널을 확인해 보면 데이터가 meta없이 생성이 되었다.

그 이유는 잘못된 정보를 보냈기 때문이다.

이걸 통해 시스템이 코드를 어느 정도 보호하고 있음을 알 수 있다.

그렇기에 단순한 object를 만든 것이 아니다.

매우 똑똑한 object를 만든 거다. mongoose에 의해서 보호 받고 있는 거다.

위 처럼 잘못된 정보를 기록하면 올바른 정보가 아니라 document데이터에 포함되지 않게 된다.

mongoose가 데이터 타입의 유효성 검사를ㄷ 도와 주고 있다.

이게 바로 데이터의 형태를 미리 정해 뒀을때 얻는 장점 중에 하나라 할 수 있다.

이전 파트에서 왜 mongoose에게 데이터 종류를 알려줘야 하나 궁금했을 거다.

올바르지 않은 데이터는 document에 기록 될수 없게 만든다.

방금까지 validation(검증)에 대한 설명이었다. mongoose가 도와주고 있음을 아는게

중요 했기 때문이다.

왜냐하면 인간은 매번 실수를 일으키는 동물이라 도움에 감사해야 하기 때문이다.

이제 database에 데이터를 저장해보도록 한다.

왜냐하면 objectdatabase에 아직 존재하지 않는다.

현재는 javascript 세계에서만 존재하고 있다. 이제 database의 세계로 넘겨줘야 한다.

이제 console.log(video); 그만 하고 video.save()를 해준다.

export const postUpload = (req, res) => {
  const { title, description, hashtags } = req.body;
  const video = new Video({
    title: title,
    description: description,
    createdAt: Date.now(),
    hashtags: hashtags.split(",").map((word) => `#${word}`),
    meta: {
      views: 0,
      rating: 0,
    },
  });
  video.save();
  return res.redirect("/");
};

이렇게 하면 이제 본격적으로 작업 할수 있게 된다.

videomongoose model인 덕에 많은 시스템 지원을 받을 수 있다.

그 중 하나가 save이다. savepromisereturn해주는데 이 말은 save작업이 끝날 때까지

기다려줘야 한다는 거다.

operation으로 또 설명하자면 javascript안에서만 존재 한다.

그래서 기다려 줄 필요가 없다. 하지만 save가 되는 순간 기다려 줘야 한다.

왜냐하면 database에 기록되고 저장되는데에는 시간이 조금 걸리기 때문이다.

기다리는 건 정말 중요한 거다.

기다림의 방법은 async를 적고 await을 적어 주는 거다.

export const postUpload = async (req, res) => {
  const { title, description, hashtags } = req.body;
  const video = new Video({
    title: title,
    description: description,
    createdAt: Date.now(),
    hashtags: hashtags.split(",").map((word) => `#${word}`),
    meta: {
      views: 0,
      rating: 0,
    },
  });
  await video.save();
  return res.redirect("/");
};

이제 database에 파일이 저장되는 것을 기다릴 수 있게 되었다.

savepromisereturn하고 그걸 await하면 documentreturn된다.

const dbVideo = await video.save();
  console.log(dbVideo);
  return res.redirect("/");

이렇게 작성해 준다. 그리고 이제 결과를 기다린다.

다시 한번 얘기 하지만 단순하지 않은 javascript object 를 만들었다.

그리고 똑똑한 javascript object는 데이터를 검증하는 것을 도와준다.

거기에 이상한 데이터를 넣으면 저장되지 않게 된다.

왜냐하면 올바르지 않은 데이터는 저장하고 싶지 않기 때문이다.

그 다음 video.save를 실행하지만 await해야한다.

그 이유는 데이터를 database에 전송하는데 시간이 걸리기 때문이다.

그렇기에 무조건 기다려야 한다. 그리고 video.save는 생성된 videoreturn해준다.

그리고 videodatabase에 속한 video이다.

새로고침을 해주고 다시 실행 해주고 upload 해준다.

This goes to DB
/5.
comments.
Posted Sun Apr 10 2022 18:38:04 GMT+0900 (대한민국 표준시).
views.

새로운 video가 생성 되었다. 이걸로 이제 video를 하나 만든거다.

이제 home에 들어갈 때마다 video.findvideo들을 불러 줄거다.

console에서도 어떻게 보이는지 보도록 한다.

✅ Server listening on port http://localhost:4000 🚀
✅Connected to DB
GET / 304 250.487 ms - -
GET /videos/upload 200 28.309 ms - 754
{
  title: 'This goes to DB',
  description: 'Seriousle',
  createdAt: 2022-04-10T09:38:04.668Z,
  hashtags: [ '#for', '#real', '#now', '#mongo' ],
  meta: { views: 0, rating: 0 },
  _id: new ObjectId("6252a57c867de2bae69b9f31"),
  __v: 0
}
POST /videos/upload 302 31.750 ms - 46
GET / 200 61.554 ms - 661

보다시피 생성한 video이다. 생긴건 저장하지 않았던 video와 같지만 이번건

database에 저장이 되었다.

몇번을 새로고침하거나 서버를 재시작해도 저장한 비디오는 계속 존재 할거다.

그 이유는 database에 저장된 데이터이기 때문이다. 굉장히 심플하게 작동한다.

알다시피 javascript object을 만들었고 해당 objectdatabase에 저장시켰다.

console.log되고 있는건 평범함 javascript object이지만

objectdatabase에 저장되어 있다는 점이 특별하다.

필요 없는 코드들은 지워 주도록 한다.

 await video.save();
  return res.redirect("/");

그리고 이제 console.log할 부분은 home이다.

export const home = async (req, res) => {
  const videos = await Video.find({});
  console.log(videos);
  return res.render("home", { pageTitle: "Home", videos });
};

이렇게 하면 database에 저장된 걸 볼수 있게 된다.

다시 새로고침을 해준고 터미널을 확인해 보면

✅ Server listening on port http://localhost:4000 🚀
✅Connected to DB
[
  {
    meta: { views: 0, rating: 0 },
    _id: new ObjectId("6252a57c867de2bae69b9f31"),
    title: 'This goes to DB',
    description: 'Seriousle',
    createdAt: 2022-04-10T09:38:04.668Z,
    hashtags: [ '#for', '#real', '#now', '#mongo' ],
    __v: 0
  }
]
GET / 304 160.181 ms - -

video를 다시 볼수 있다. 이걸로 object들로 구성된 array가 생겼다.

아무도 부정 할수 없는 진짜 video이다. 진짜라는 의미는 database상 존재 한다는 말이다.

이제 mongo console로 돌아가서 show dbs를 실행하면 wetube database 가 생긴걸 알수 있다.

(이미 전 파트에서 생겼지만 ...현시점에선 이게 중요한 사실은 아닌것 같아서 넘어가도록 햔다.)

그럼 이제 wetubeuse해준다. (터미널에서 use wetube)

show collections를 실행 할거다. (터미널에서 show collections)

그러면 이제 videos가 있음을 확인 할수 있다.

collections가 뭐냐하면 document들의 묶음이라 생각하면 된다.

이 경우에는 document 종류가 video만 있어서 video만 보이는 거다.

이제 video document들로 구성된 video collection을 갖게 되었다.

help를 사용해서 database 탐험 해볼수 있다.

예를 들어 db들을 볼수 있고 show collections도 있고 show users도 있다.

collection 안의 object들도 확인 할수 있다.

이 말은 db.videos.find() 실행 하면

{ "_id" : ObjectId("6252a57c867de2bae69b9f31"), "title" : "This goes to DB", "description" : "Seriousle", "createdAt" : ISODate("2022-04-10T09:38:04.668Z"), "hashtags" : [ "#for", "#real", "#now", "#mongo" ], "meta" : { "views" : 0, "rating" : 0 }, "__v" : 0 }

이런 데이터가 나온다. 이것이 바로 mongodb database이다.

objectmongo db에 존재 하는 모습이다.

ID,hashtags,description이 보이고 ISO Data도 있고 그리고 meta도 완벽하게 작동 중이다.

이걸로 database에 무엇인가를 저장하고 있다는 걸 알게 되었다.

그리고 어떤 것이든 하는 방법은 두가지 이상이다.

하나는 javascript object 를 만들고 objectdatabase에 저장하는 것이고

또 다른 하나의 방식은 이렇게 해주는거다.

export const postUpload = async (req, res) => {
  const { title, description, hashtags } = req.body;
  await Video.create({
    title: title,
    description: description,
    createdAt: Date.now(),
    hashtags: hashtags.split(",").map((word) => `#${word}`),
    meta: {
      views: 0,
      rating: 0,
    },
  });
  return res.redirect("/");
};

video.create는 방금 작성한 코드와 기능은 똑같은데 하지만 javascript object를 만들어 주는 과정을 안해줘도 된다.

왜냐하면 위 코드가 그걸 자동적으로 해주기 때문이다.

이게 두가지 방식이고 mongoose documentation에서 확인이 가능하다.

https://mongoosejs.com/docs/documents.html

하나는 처음에 말한 save방식이고 두번째는 create방식이다.

https://mongoosejs.com/docs/models.html

const Tank = mongoose.model('Tank', yourSchema);

const small = new Tank({ size: 'small' });
small.save(function (err) {
  if (err) return handleError(err);
  // saved!
});

// or

Tank.create({ size: 'small' }, function (err, small) {
  if (err) return handleError(err);
  // saved!
});

// or, for inserting large batches of documents
Tank.insertMany([{ size: 'small' }], function(err) {

});

전자는 new,object,save를 하면 되고

후자는 video model만 있다면 create로 복잡한 과정을 건너 뛴다.

function (err, small) {
  if (err) return handleError(err);

여기를 보면 callback을 하나 확인 할수 있는데 여기에 await를 사용 해줄수 있다.

이 과정에 에러가 발생 할수 있다. 그러니깐 trycatch를 사용해 준다.

이걸 확인 하기 위해서 고의로 에러를 낸다.

    createdAt: "lalalalala",

이 부분을 string으로 바꿔준다. 이렇게 올바르지 않은 데이터 형식을 가진 데이터를

create하면 어떻게 될까?

video 생성을 통해 확인해 본다. upload를 해주면 ?

업로드에 대한 결과값이 출력되지 않고 있다. 그 이유는 console에 떠있는 오류를 통해

확인 할수 있다.

에러를 보면 createdAt의 값이 잘못 되었다고 말하고 있다.

보다시피 database는 실수들을 방지해 주고 있다.

이것이 데이터 형태를 만든 이유를 한 번 더 보여주고 있다.

다시 보자면 이상한 값을 가진 데이터를 전송하고 있다.

왜냐하면 위에서 해당 값은 date 형태의 데이터라 정의 해놨기 때문이다.

그렇기에 console은 틀렸다고 말 하고 있는 거다.

validation에 문제가 있는 거다.

date 형식이 아닌 데이터는 지나가지 못하는 거다.

profile
꿈꾸는 개발자

0개의 댓글