Our First Query # 01

이전 파트에서 비디오 파일의 데이터 형식을 정의했다.

그 다음 해당 형식을 가진 model을 만들었다.

그리고 해당 modeldefaultexport 한 뒤 import해서

preload를 가능하게 만들었다. 이렇게 하는 이유는 model을 미리 compile또는

create해야 필요할 때 해당 model을 사용 할수 있어서다.

나중에 더욱 많은 것을 import하게 될거다.

import "./models/Users"; import "./models/Comments";

이런 import가 계속 추가 되면 목록이 너무 많아져서 관리하기 좋지 못하다.

따지고 보면 이런 importserver와는 큰 연관이 없다.

그래서 새 파일을 생성해서 해당 형식의 import들을 분리해서 관리 해줄거다.

src폴더 안에 init.js 파일을 생성 해준다.

init.js 에서

import "./db";
import "./models/Video";

이 파일은 모든 걸 초기화 시켜 줄것이다. databasevideoimport해주고

application을 작동 시킬거다.

그걸 위해 server.js에서 init.js로 옮겨 준다.

const handleListening = () =>
  console.log(`✅ Server listening on port http://localhost:${PORT} 🚀`);

app.listen(PORT, handleListening);

이 파일에서는 PORT가 정의도지 않아서 일시적으로 오류가 뜰거다.

PORTserver.js에서 옮겨준다.

const PORT = 4000;

app이 정의 되지 않아서 오류가 남아 있을 거다. 이걸 해결하려면

먼저 server.js에서 appconfigure하고

export default app; 을 해준다.

이렇게 export한 파일을 여기에 import해줄거다.

import app from "./server";

방금 작성한 코드로 init.jsapp을 작동 시킬 수 있게 되었다.

물론 필요한 import 모두 가져 온 뒤에 가능하다.

지금 관련된 부분들에 따라 분리 시키고 있는데 그 이유는 server.jsexporess 된것 들과

serverconfiguration에 관련된 코드만 처리하기 위해 만들어 졌다.

databasemodel 같은 것들을 import를 하기 위함은 아니다.

일단 저장해주고 console.log를 확인해 보면 정상적으로 작동하지는 않는다.

왜냐하면 nodemon은 현재 server.js를 관찰하는데 server.jsappexport할 뿐

작동 시키지는 않기 때문이다.

그래서 package.json을 수정해서 이 문제를 해결해 보도록 하겠다.

src에 있는 server.js대신 init.js로 연결 시키는 거다.

이렇게 하고 재시작을 해보면 잘 작동한다.

이제 관련된 것들끼리 분리 시켜주고 있다.

server.jsserver관련 코드만 처리하고 init.js는 필요한 모든 것들을 import 시키는

역할을 담당 할거다.

import에 이상이 없다면 init.jsapp을 실행 시킬거다.

이제서야 video 관련 코드를 짤 수 있게 되었다.

여기서 한가지 집고 넘어가자. databasevideo에 대한 접근은 어려울까?

천만에 전혀 어렵지 않다. 그전에 하나 정리를 해주고 넘어 가도록 하자.

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같은 것들 말이다.

일단 trendinghome으로 바꿔 준다.

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";

해당 파일에서 먼저 videoimport 해준다.

이제 database와 연결해야 하는데 그걸 하는 방법은 mongoose documentation을 보면 된다.

https://mongoosejs.com/docs/queries.html 해당 사이트를 보면

Mongoose models provide several static helper functions for CRUD operations. 이 문구가 보인다.

mongoosemodel들은 CRUD operaion을 돕는 많은 function들을 제공한다.

보다시피 많은 function들이 존재한다. 예를 들어 Model.find()를 사용 하고자 하면

Video.find()를 입력해주면 된다. Video.find()는 사용법이 두가지가 있다.

먼저 callback function을 활용하는 방법이 있고

두번째로는 promise를 활용하는 방법이 있다.

이게 무슨 뜻이냐면 이걸 이해하기 위해서는 javascriptpromise

그리고 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의 전송 속도가

느릴수도 있다. 이 외에도 데이터 처리 시 많은 상황이 발생 할수 있다.

왜냐하면 databasejavascript 밖에 존재하기 때문이다.

두가지 방법을 쓸 수 있는데 하나는 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을 전송하는 거다.

callbackerrdocs라는 signature를 가진다.

그 부분이 찾는 function이다. errdocs를 수신하는 function이 생긴거다.

참고로 videos 라 바꿔도 상관 없다. 그리고 그 다음은 callback explanation이기에

다음 파트에서 하기로 한다.

좋은 웹페이지 즐겨찾기