이전 파트에서 비디오 파일의 데이터 형식을 정의했다.
그 다음 해당 형식을 가진 model
을 만들었다.
그리고 해당 model
을 default
로 export
한 뒤 import
해서
preload
를 가능하게 만들었다. 이렇게 하는 이유는 model
을 미리 compile
또는
create
해야 필요할 때 해당 model
을 사용 할수 있어서다.
나중에 더욱 많은 것을
import
하게 될거다.
import "./models/Users";
import "./models/Comments";
이런 import
가 계속 추가 되면 목록이 너무 많아져서 관리하기 좋지 못하다.
따지고 보면 이런 import
는 server
와는 큰 연관이 없다.
그래서 새 파일을 생성해서 해당 형식의 import
들을 분리해서 관리 해줄거다.
src
폴더 안에init.js
파일을 생성 해준다.
init.js
에서
import "./db";
import "./models/Video";
이 파일은 모든 걸 초기화 시켜 줄것이다. database
와 video
를 import
해주고
application
을 작동 시킬거다.
그걸 위해 server.js
에서 init.js
로 옮겨 준다.
const handleListening = () =>
console.log(`✅ Server listening on port http://localhost:${PORT} 🚀`);
app.listen(PORT, handleListening);
이 파일에서는 PORT
가 정의도지 않아서 일시적으로 오류가 뜰거다.
PORT
도 server.js
에서 옮겨준다.
const PORT = 4000;
app
이 정의 되지 않아서 오류가 남아 있을 거다. 이걸 해결하려면
먼저 server.js
에서 app
을 configure
하고
export default app; 을 해준다.
이렇게 export
한 파일을 여기에 import
해줄거다.
import app from "./server";
방금 작성한 코드로 init.js
는 app
을 작동 시킬 수 있게 되었다.
물론 필요한 import
모두 가져 온 뒤에 가능하다.
지금 관련된 부분들에 따라 분리 시키고 있는데 그 이유는 server.js
는 exporess
된것 들과
server
의 configuration
에 관련된 코드만 처리하기 위해 만들어 졌다.
database
나 model
같은 것들을 import
를 하기 위함은 아니다.
일단 저장해주고 console.log
를 확인해 보면 정상적으로 작동하지는 않는다.
왜냐하면 nodemon
은 현재 server.js
를 관찰하는데 server.js
는 app
을 export
할 뿐
작동 시키지는 않기 때문이다.
그래서 package.json
을 수정해서 이 문제를 해결해 보도록 하겠다.
src
에 있는 server.js
대신 init.js
로 연결 시키는 거다.
이렇게 하고 재시작을 해보면 잘 작동한다.
이제 관련된 것들끼리 분리 시켜주고 있다.
server.js
는 server
관련 코드만 처리하고 init.js
는 필요한 모든 것들을 import
시키는
역할을 담당 할거다.
import
에 이상이 없다면 init.js
는 app
을 실행 시킬거다.
이제서야 video
관련 코드를 짤 수 있게 되었다.
여기서 한가지 집고 넘어가자.
database
내video
에 대한 접근은 어려울까?
천만에 전혀 어렵지 않다. 그전에 하나 정리를 해주고 넘어 가도록 하자.
videoController.js
에서
let videos = [
{
title: "First Video",
rating: 5,
comments: 10,
createdAt: "2 hours ago ",
views: 100,
id: 1,
},
{
title: "Second Video",
rating: 3,
comments: 5,
createdAt: "25 minutes ago ",
views: 20,
id: 2,
},
{
title: "Third Video",
rating: 4,
comments: 8,
createdAt: "2 minutes ago ",
views: 80,
id: 3,
},
];
드디어 실존 하지 않는 database
를 지우게 되었다.
방금 작업으로 videos
는 존재하지 않게 되었다.
export const trending = (req, res) => {
return res.render("home", { pageTitle: "Home" });
};
export const watch = (req, res) => {
const { id } = req.params;
return res.render("watch", { pageTitle: `Watching` });
};
export const getEdit = (req, res) => {
const { id } = req.params;
return res.render("Edit", { pageTitle: `Editing` });
};
export const postEdit = (req, res) => {
const { id } = req.params;
const { title } = req.body;
return res.redirect(`/videos/${id}`);
};
export const getUpload = (req, res) => {
return res.render("upload", { pageTitle: "Upload Video" });
};
export const postUpload = (req, res) => {
const { title } = req.body;
return res.redirect("/");
};
존재하지 않는 videos
들을 다 삭제해 주었다. 이제 존재하지 않는 데이터들은 다 삭제 되었다.
남은 것들은 express
관련 코드들이다.
videoController
에 있는 render
같은 것들 말이다.
일단 trending
을 home
으로 바꿔 준다.
export const home = (req, res) => {
그리고 이 contorller
의 이름을 바꿔 줬으니 globalRouter
로 가서 해당 파일의
controller
이름도 바꿔준다.
import { home, search } from "../controllers/videoController";
globalRouter.get("/", home);
이제
video model
을 어떻게 사용할까?
controller
폴더 안의 파일들을 수정해주면 된다. videoController.js
를 예로 들어 보겠다.
videoController.js
에서
import video from "../models/Video";
해당 파일에서 먼저 video
를 import
해준다.
이제 database
와 연결해야 하는데 그걸 하는 방법은 mongoose documentation
을 보면 된다.
https://mongoosejs.com/docs/queries.html 해당 사이트를 보면
Mongoose models provide several static helper functions for CRUD operations.
이 문구가 보인다.
mongoose
의 model
들은 CRUD operaion
을 돕는 많은 function
들을 제공한다.
보다시피 많은 function
들이 존재한다. 예를 들어 Model.find()
를 사용 하고자 하면
Video.find()
를 입력해주면 된다.Video.find()
는 사용법이 두가지가 있다.
먼저 callback function
을 활용하는 방법이 있고
두번째로는 promise
를 활용하는 방법이 있다.
이게 무슨 뜻이냐면 이걸 이해하기 위해서는 javascript
와 promise
그리고 callback
의 작동 방식을 이해해야한다.
callback
이 무엇인지 예시를 들어보면 callback
이란 무언가가 발생하고 난 다음
호출되는 function
을 말한다.
init.js
를 예로 들자면
app.listen(PORT, handleListening);
이 부분을 callback
이라 할수 있다. PORT
를 먼저 listen
하고 있는데
callback
은 특별한 것이 아니라 javascript
에서 기다림을 표현하는 하나의 방법이라
생각하면 편하다.
여기서도 연결이 확인 되면 특정 function
이 발동 하고 있는 거다.
예를 들자면 '4000 PORT
'에 연결을 해야하는데 해당 코드는 바로 실행되지 않을수 있다는 거다.
백만분의 일 초라 해도 결과값 도출을 기다려야 한다는 말이다.
Video
도 마찬가지이다. database
를 보면 데이터가 전송되는 것을 기다려야 한다.
몇 초 안 걸릴 수도 있고 0.000001초가 걸릴 수도 있지만 데이터가 완전히 전송될때 까지
꼭 기다려야 한다는 말이다.
그리고 코드 실행 중 오류가 발생 할 가능성도 있다.
왜냐하면 받는 데이터는 javascript
파일 속에 없기 때문이다.
javascript
파일 속에 없는 데이터 이것이 바로 database
라는 거다.
어쨌든 모르는 오류가 생길 수도 있고 다양한 상황에 따라 데이터 처리에 시간이 걸릴 수도 있다.
좀 더 쉬운 예를 들어 설명하자면 console.log( 1 + 1 )
이런 건 javascript
가
혼자 처리 할수 있다.
javascript
는 해당 코드를 읽음과 동시에 출력하고 다음 작업으로 넘어 갈 거다.
기다림도 필요 없고 일어날 오류가 없기 때문이다. 아무것도 없는 것과 비슷한 속도로 처리 될거다.
하지만 Video.find()
의 경우 database
가 종료 되거나, 바쁘거나 database
의 전송 속도가
느릴수도 있다. 이 외에도 데이터 처리 시 많은 상황이 발생 할수 있다.
왜냐하면 database
는 javascript
밖에 존재하기 때문이다.
두가지 방법을 쓸 수 있는데 하나는
callback
이고 나머지는promise
이다.
promise
가 제일 좋은 방식이지만 callback
을 활용하는 방법부터 배워서
각 작동 방식을 이해 해보도록 하겠다.
callback
은 어떻게 작동 시키는 걸까?
init.js
에서 봤지만 configuration
이랑 호출 할 function
이 필요하다.
videoController.js
에서
export const home = (req, res) => {
Video.find({}, (error, videos) => {});
Video.find()
이 안에 configuration
을 넣어주면 되는데
일단 여기에 모든 형태의 비디오를 찾는다고 하고 중괄호는 search terms
를 나타내는데
search terms
가 비어있으면 모든 형식을 찾는다는 것을 뜻한다.
일단 이것으로 모든 형태의 비디오를 찾게 되고 다음 단계로 callback
을 전송하는 거다.
callback
은 err
와 docs
라는 signature
를 가진다.
그 부분이 찾는 function
이다. err
와 docs
를 수신하는 function
이 생긴거다.
참고로 videos
라 바꿔도 상관 없다. 그리고 그 다음은 callback explanation
이기에
다음 파트에서 하기로 한다.