videoController.js 내에 이런 가짜 database를 생성했다 하자.
let videos = [
{
title: "First Video",
rating: 5,
comments: 2,
createdAt: "2 minutes ago",
views: 59,
id: 1,
},
{
title: "Second Video",
rating: 5,
comments: 2,
createdAt: "2 minutes ago",
views: 59,
id: 2,
},
{
title: "Third Video",
rating: 5,
comments: 2,
createdAt: "2 minutes ago",
views: 59,
id: 3,
},
];
객체 video의 id를 이용해 각 video에 대한 링크로 이동하는 방법
a(href="/videos/" + video.id)=video.title
a(href=`/videos/${video.id}`)=video.title
# 기호를 써서 text와 함께 작성하는 방식은 attribute에서는 통하지 않는다.
videoController.js
export const see = (req, res) =>
{
const {id} = req.params; //const id = req.params.id;
const video = videos[id - 1];
return res.render("watch", {pageTitle : `Watching ${video.title}`});
}
watch.pug
extends base.pug
block content
h3 #{video.views} #{video.views == 1 ? "view" : "views"}
//- 삼항 연산자
a(href=`${video.id}/edit`) Edit Video →
//- /edit : root 경로/edit(절대 경로), edit : 상대 경로
videoController.js
export const edit = (req, res) => {
const {id} = req.params; //const id = req.params.id;
const video = videos[id - 1];
return res.render("edit", {pageTitle : `Editing: ${video.title}`});
}
get, post
get : 검색을 할 때 그 검색어를 주소창에 포함시킬 때 사용. 정보가 url로 들어간다. 데이터를 받기만 할 때 사용
post : 파일을 보낼 때, database에 있는 값을 바꾸는 뭔가를 보낼 때, 로그인할 때 사용
edit.pug
extends base.pug
block content
h4 Change Title of video
form(method="POST")
//- action이 없다면 같은 url로 이동한다.
input(name="title", placeholder="Video Title", value=video.title)
input(value="Save", type="submit")
vidoeRouter.js
videoRouter.route("/:id(\\d+)/edit").get(getEdit).post(postEdit);
/*
videoRouter.get("/:id(\\d+)/edit", getEdit);
videoRouter.post("/:id(\\d+)/edit", postEdit);
*/
server.js
app.use(express.urlencoded({extended:true}));
//express가 form의 value를 이해할 수 있도록 하고, 우리가 쓸 수 있는 javascript 형식으로 변환
videoController.js
export const postEdit = (req, res) => {
const {id} = req.params;
const {title} = req.body; //const title = req.body.title
const video = videos[id - 1];
video.title = title; //form에서 받은 title로 변경
return res.redirect(`/videos/${id}`);
//브라우저가 redirect(자동으로 이동)하도록 한다.
};
단, videos는 가짜 database이기에 서버를 껐다 키면 수정한 정보들이 원래대로 돌아온다.
upload.pug
extends base.pug
block content
form(method="POST")
input(name="title" placeholder="Title", required, type="text")
input(type="submit", value="Upload Video")
videoController.js
export const getUpload = (req, res) => {
return res.render("upload", {pageTitle: "Upload Video"});
};
export const postUpload = (req, res) => {
const {title} = req.body;
const newVideo = {
title, //newVideo의 title은 req.body의 title과 동일
rating: 0,
comments: 0,
createdAt: "just now",
views: 0,
id: videos.length + 1,
}
videos.push(newVideo);
return res.redirect("/");
};
videoRouter.js
videoRouter.get("/upload", getUpload);
videoRouter.post("/upload", postUpload);
이제 실제 database를 써보자.
MongoDB
document-based database
데이터를 package.json을 저장하는 것처럼 JSON-like-documents로 저장한다.
document 내부를 검색, 수정, 삭제 등을 할 수 있게 한다.
mongoose
node.js와 mongoDB를 이어주는 package. node.js에서 mongoDB와 상호작용하기 위해 사용.
설치 방식
설치 순서
1. mongodb server 설치
2. mongoDB Shell 설치 == mongosh 설치
3. 환경 변수에 추가
1-1. https://www.mongodb.com/try/download/community 접속
1-2. 알맞은 platform에 msi package를 다운 ex) 6.0.2 Windows msi
1-3. 다운받은거 실행
1-4. 전부 yes해주고 나면 MongoDBCompass까지 설치
1-5. powershell을 켜서 md \data\db 를 입력.
2-1. https://www.mongodb.com/try/download/shell 접속
2-2. 알맞은 platform에 zip package를 다운
2-3. 원하는 곳에 zip파일을 풀기. ex) C:\
3-1. 윈도우 검색창에 "시스템 환경 변수 편집" 접속
3-2. "고급"으로 가서 맨아래 "환경 변수" 클릭
3-3. 사용자에 대한 사용자 변수의 "변수" 부분에 "Path"를 클릭후 "편집" 클릭
3-4. mongoDB, mongoDB Shell bin 경로를 추가
ex) C:\Program Files\MongoDB\Server\6.0\bin
ex) C:\mongosh-1.6.0-win32-x64\bin
mongod, mongosh 명령어 실행
mongod 명령어는 실행 후 터미널이 얼어붙을 수 있지만 상관 없음
mongosh는 실행되어야 한다.
npm i mongoose로 mongoose 설치
server.js 옆에 db.js 파일 생성
db.js
import mongoose from "mongoose";
mongoose.connect("mongodb://127.0.0.1:27017/wetube");
//mongodb에 새로운 database를 만드는 법 : mongosh를 실행해 나온 url 뒤에 database 이름을 적어준다.
//mongoose는 wetube라는 mongodb database로 연결해 준다.
const db = mongoose.connection;
const handleOpen = () => console.log("Connected to DB")
const handleError = (error) => console.log("DB Error", error);
db.on("error", handleError); //error가 발생하면 handleError 실행
db.once("open", handleOpen); //connection이 발생(연결 또는 열리게 되면)하면 handleOpen 실행
//on : 여러 번 발생 가능
//once : 단 한 번 발생 가능
server.js
import "./db";
//db.js 파일 자체를 import. 서버가 이 라인을 보는 순간 이 파일이 import되며 mongodb에 연결된다.
CRUD
Create(생성), Read(읽기), Update(수정), Delete(삭제)
mongoose는 node.js와 mongoDB를 이어주는 역할을 하는데, 이를 위해서는 mongoose에게 우리의 application의 데이터들이 어떻게 생겼는지 알려줘야 한다. 그렇게 한다면 mongoose는 우리의 데이터를 CRUD하는 것을 돕는다.
database는 데이터의 구체적인 값이 아닌, 데이터의 형태를 알아야 한다. 이러한 데이터의 형태를 model이라 하고, 이 model을 database에게 설명해 주어야 한다. database는 model을 이용해 model을 CRUD하는 것을 돕는다.
models 폴더 생성 -> Video.js 파일 생성
Video.js
import mongoose from "mongoose";
//model의 형태 : schema
const videoSchema = new mongoose.Schema({
title: String,
description: String, //{type: String}과 동일
createdAt: Date,
hashtags: [{type: String}],
meta: {
views: Number,
rating: Number,
},
});
const Video = mongoose.model("Video", videoSchema);
//model 생성 : model의 이름, 데이터의 형식인 Schema로 구성
//Video는 videoSchema의 형식을 따르고 있다.
export default Video;
server.js
import "./models/Video"
//server.js에 database를 import해서 연결
//위 연결로 db는 video model을 인지한다.
이때, model을 import하는 것은 server와 큰 관련이 없으므로 init.js로 분리한다.
package.json
"scripts": {
"dev": "nodemon --exec babel-node src/init.js"
},
server.js
import express from "express";
import morgan from "morgan";
import globalRouter from "./routers/globalRouter";
import userRouter from "./routers/userRouter"
import videoRouter from "./routers/videoRouter"
const app = express();
const logger = morgan("dev");
app.set("view engine", "pug")
app.set("views", process.cwd() + "/src/views");
app.use(logger);
app.use(express.urlencoded({extended:true}));
app.use("/", globalRouter);
app.use("/users", userRouter);
app.use("/videos", videoRouter);
export default app;
init.js
import "./db";
import "./models/Video";
import app from "./server";
const PORT = 4000;
const handleListening = () =>
console.log(`Server listening on port http://localhost:${PORT}`);
app.listen(PORT, handleListening);
백엔드 개발 - Node.js(6) : callback, promise, async-await (0) | 2023.04.03 |
---|---|
백엔드 개발 - Node.js(4) : pug (0) | 2023.03.28 |
백엔드 개발 - Node.js(3) : router, export (0) | 2023.03.26 |
백엔드 개발 - Node.js(2) : request, respond, middleware (0) | 2023.03.23 |
백엔드 개발 - Node.js(1) : setup (0) | 2023.03.20 |
댓글 영역