전 단계에서
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
으로 변환 된다는 말이다.
보다시피 시스템이 도와주고 있는 거다. 이런 작은 도움 만으로도 보다 쾌적하게 코딩을 할수 있게 된다.
일단 이 코드는 원래 상태로 되돌려 놓는다.
그리고
views
와rating
을 보면number
로 설정이 되어 있다.
이걸 반대로 string
으로 해놓으면 어떻게 될까? 이것도 한번 시도해 본다.
터미널을 확인해 보면 데이터가 meta
없이 생성이 되었다.
그 이유는 잘못된 정보를 보냈기 때문이다.
이걸 통해 시스템이 코드를 어느 정도 보호하고 있음을 알 수 있다.
그렇기에 단순한 object
를 만든 것이 아니다.
매우 똑똑한 object
를 만든 거다. mongoose
에 의해서 보호 받고 있는 거다.
위 처럼 잘못된 정보를 기록하면 올바른 정보가 아니라 document
데이터에 포함되지 않게 된다.
mongoose
가 데이터 타입의 유효성 검사를ㄷ 도와 주고 있다.
이게 바로 데이터의 형태를 미리 정해 뒀을때 얻는 장점 중에 하나라 할 수 있다.
이전 파트에서 왜 mongoose
에게 데이터 종류를 알려줘야 하나 궁금했을 거다.
올바르지 않은 데이터는 document
에 기록 될수 없게 만든다.
방금까지 validation(검증)
에 대한 설명이었다. mongoose
가 도와주고 있음을 아는게
중요 했기 때문이다.
왜냐하면 인간은 매번 실수를 일으키는 동물이라 도움에 감사해야 하기 때문이다.
이제
database
에 데이터를 저장해보도록 한다.
왜냐하면 object
는 database
에 아직 존재하지 않는다.
현재는 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("/");
};
이렇게 하면 이제 본격적으로 작업 할수 있게 된다.
video
가 mongoose model
인 덕에 많은 시스템 지원을 받을 수 있다.
그 중 하나가 save
이다. save
는 promise
를 return
해주는데 이 말은 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
에 파일이 저장되는 것을 기다릴 수 있게 되었다.
save
는 promise
를 return
하고 그걸 await
하면 document
가 return
된다.
const dbVideo = await video.save();
console.log(dbVideo);
return res.redirect("/");
이렇게 작성해 준다. 그리고 이제 결과를 기다린다.
다시 한번 얘기 하지만 단순하지 않은 javascript object
를 만들었다.
그리고 똑똑한 javascript object
는 데이터를 검증하는 것을 도와준다.
거기에 이상한 데이터를 넣으면 저장되지 않게 된다.
왜냐하면 올바르지 않은 데이터는 저장하고 싶지 않기 때문이다.
그 다음 video.save
를 실행하지만 await
해야한다.
그 이유는 데이터를 database
에 전송하는데 시간이 걸리기 때문이다.
그렇기에 무조건 기다려야 한다. 그리고 video.save
는 생성된 video
를 return
해준다.
그리고 video
는 database
에 속한 video
이다.
새로고침을 해주고 다시 실행 해주고 upload
해준다.
This goes to DB
/5.
comments.
Posted Sun Apr 10 2022 18:38:04 GMT+0900 (대한민국 표준시).
views.
새로운 video
가 생성 되었다. 이걸로 이제 video
를 하나 만든거다.
이제 home
에 들어갈 때마다 video.find
는 video
들을 불러 줄거다.
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
을 만들었고 해당 object
을 database
에 저장시켰다.
console.log
되고 있는건 평범함 javascript object
이지만
object
가 database
에 저장되어 있다는 점이 특별하다.
필요 없는 코드들은 지워 주도록 한다.
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
가 생긴걸 알수 있다.
(이미 전 파트에서 생겼지만 ...현시점에선 이게 중요한 사실은 아닌것 같아서 넘어가도록 햔다.)
그럼 이제 wetube
를 use
해준다. (터미널에서 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
이다.
object
가 mongo db
에 존재 하는 모습이다.
ID
,hashtags
,description
이 보이고 ISO Data
도 있고 그리고 meta
도 완벽하게 작동 중이다.
이걸로 database
에 무엇인가를 저장하고 있다는 걸 알게 되었다.
그리고 어떤 것이든 하는 방법은 두가지 이상이다.
하나는 javascript object
를 만들고 object
를 database
에 저장하는 것이고
또 다른 하나의 방식은 이렇게 해주는거다.
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
를 사용 해줄수 있다.
이 과정에 에러가 발생 할수 있다. 그러니깐 try
와 catch
를 사용해 준다.
이걸 확인 하기 위해서 고의로 에러를 낸다.
createdAt: "lalalalala",
이 부분을 string
으로 바꿔준다. 이렇게 올바르지 않은 데이터 형식을 가진 데이터를
create
하면 어떻게 될까?
video
생성을 통해 확인해 본다. upload
를 해주면 ?
업로드에 대한 결과값이 출력되지 않고 있다. 그 이유는 console
에 떠있는 오류를 통해
확인 할수 있다.
에러를 보면 createdAt
의 값이 잘못 되었다고 말하고 있다.
보다시피 database
는 실수들을 방지해 주고 있다.
이것이 데이터 형태를 만든 이유를 한 번 더 보여주고 있다.
다시 보자면 이상한 값을 가진 데이터를 전송하고 있다.
왜냐하면 위에서 해당 값은 date
형태의 데이터라 정의 해놨기 때문이다.
그렇기에 console
은 틀렸다고 말 하고 있는 거다.
validation
에 문제가 있는 거다.
date
형식이 아닌 데이터는 지나가지 못하는 거다.