첫번째 게시글부터 차례대로 이어지는 프로젝트입니다
2021.06.25 - [개발/Node.js] - (1) Node.js, MongoDB 로 TODO 만들기 - 디렉토리 설정, app.js 작성
2021.06.25 - [개발/Node.js] - (2) Node.js, MongoDB 로 TODO 만들기 - 라우터 설정, 리팩토링
todo list를 작성해서 mongo db에 저장하려면
먼저 구조(스키마)가 있어야한다
스키마를 정의하는 부분은 매우 간단하다
1. models 폴더와 todoTask.js 파일 생성
Todo
└ node_modules
└ [모듈들]
└ public
└ models
└ todoTask.js
└ controllers
└ todo.js
└ routes
└ index.js
└ todo.js
└ views
└todo.ejs
└ app.js
└ package.json
todoTask는 mongoDB에 todo 리스트를 저장할때 담겨질 상자라고 보면 된다
미리 구조를 정의해두고 그 구조에 담아서 몽고디비에 보내고 꺼내는 것이다
// Todo Schema
const mongoose = require('mongoose');
const todoTaskSchema = new mongoose.Schema({
content: {
type: String,
required: true
},
date: {
type: String,
required: true
}
});
module.exports = mongoose.model('TodoTask', todoTaskSchema);
mongoose 모듈을 불러와주고 mongoose.Schema를 통해 스키마 객체를 만들어준다
todo 를 작성할 때 필요한건 적은 시간과 내용이기 때문에 content와 date를 설정해주었다
이렇게 스키마 객체를 만들면 mongodb에 객체를 담을 컬렉션이 생성된다
그리고 module.exports를 통해 mongoose의 모델로 TodoTask를 사용할 수 있도록 한다
2. controllers/todo.js 작성
이제 스키마를 가지고 todo를 작성하고, 읽어오고, 수정하고, 삭제하는 내용의 함수를 작성할것이다
// Model
const TodoTask = require("../models/todoTask");
// KST Setting
var moment = require('moment-timezone');
moment.tz.setDefault("Asia/Seoul");
먼저 필요한 모듈들을 불러와서 변수에 저장해주는데
투두리스트를 작성시 Date를 현재 시간으로 셋팅해주기 위해 필요한 moment-timezone 모듈을 불러와서
Default를 한국으로 맞춰준다
먼저 routes/todo.js에 있던 function들을 다시 살펴보자
// Controller 를 불러와서 exports 메소드 사용
const controller = require("../controllers/todo");
// Main
router.get('/', controller.get); // http://localhost:3000/todo/
// Write
router.post('/write', controller.write); // http://localhost:3000/todo/write
// Edit
router.get("/edit/:id", controller.edit);
// Update
router.post("/update/:id", controller.update);
// Remove
router.get("/remove/:id", controller.remove);
controller.get 은 exports.get으로
controller.write 는 exports.write로 작성하면
외부에서 controller.(메소드) 이렇게 사용할 수 있다
이제 다시 controllers/todo.js 로 돌아와서 get부터 작성하자
// 첫 페이지
exports.get = function(req, res){
console.log("------------!!Todo!!------------");
TodoTask.find({}, null, {sort: {date: -1}}, (err, tasks) => {
res.render("todo", { todoTasks: tasks });
});
};
처음 보여질 메인 화면에는 작성했던 투두 리스트들이 보여야하기때문에
TodoTask.find()로 tasks들을 가져와 "todo"라는 페이지에 todoTasks라는 이름으로 보낸다
갑자기 TodoTask는 어디서 나온거야!?
라고 할 수도 있지만 우리는 models/todoTask.js 에
module.exports = mongoose.model('TodoTask', todoTaskSchema);
를 작성했기 때문에 TodoTask라는 이름으로 todoTaskSchema에 접근할 수 있게 된것이다
find라는 메소드는
//Description
[Model].find(filter, [options], [callback]);
//Example
TodoTask.find({}, {sort: {date: -1}}, function(err, tasks){
res.render("todo", {todoTasks: tasks});
});
이런식으로 사용 되는데 이 부분에서는
filter : {} 모든 데이터
options : {sort: {date: -1}} 정렬 - date를 기준으로 내림차순으로
callback : function(err, tasks){} tasks로 받아와 res.render로 todo 페이지를 보여줘라
이렇게 사용된 것!
나도 여기서 처음 MongoDB를 배웠는데
Oracle 이나 MySQL만 사용했던 사람 입장에서는
SQL 쿼리 없이 DB를 불러온다고?
하면서 의아했다 ㅋㅋㅋ 너무 신기하고 편하잖아..?
그리고 남은 write, edit, update, remove 를 작성한다
// 작성
exports.write = async function(req, res){
try{
const todoTask = new TodoTask({ //새로운 TodoTask를 만들어서 todoTask에 저장
content: req.body.content, //입력한 부분
date: moment().format("YYYY-MM-DD HH:mm:ss") //현재 시간
});
await todoTask.save(); //save()를 통해 db에 저장
console.log("==== Success!! Save New TodoTask ====");
console.table([{id: todoTask._id, content: todoTask.content, date: todoTask.date}]);
res.redirect("/todo"); //localhost:3000/todo로 귀환
}catch(err){
console.err("==== Fail!! Save TodoTask ====");
res.redirect("/todo");
}
};
// 편집
exports.edit = function(req, res){
const id = req.params.id; //파라미터로 받은 id를 id에 저장
TodoTask.find({}, null, {sort: {date: -1}}, (err, tasks) => { //db에서 조회해서
res.render("todo-edit", { todoTasks: tasks, idTask: id }); //todo-edit.ejs에 id와 함께 보낸다
});
};
// 수정
exports.update = function(req, res){
const id = req.params.id;
TodoTask.findByIdAndUpdate(id, { content: req.body.content }, err => { //해당 id값의 content를 변경
if(err){
console.log("==== Fail!! Update TodoTask ====");
console.error(err);
}
console.log("==== Success!! Update TodoTask ====");
console.log("id: " + id + "\nchanged content: " + req.body.content);
res.redirect("/todo");
});
}
//삭제
exports.remove = function(req, res){
const id = req.params.id;
TodoTask.findByIdAndRemove(id, err => { //해당 id의 데이터를 삭제
if(err){
console.log("==== Fail!! Remove TodoTask ====")
console.error(err);
}
console.log("==== Success!! Remove TodoTask ====");
console.log("id: " + id);
res.redirect("/todo");
});
};
이렇게 전부 작성해준다
find(), save() findByIdAndUpdate() 등 mongoose 관련 메소드가 이해가 안된다면
https://mongoosejs.com/docs/guide.html
여기서 확인하자!
이제 컨트롤러 부분도 다 작성했고, ejs파일 프론트 부분만 작성하면 된다!!
(1) 서버 설정 app.js
(2) 경로 설정 routes/todo.js
(3) 모델 설정 models/todo.js
(4) 서비스 설정 controllers/todo.js
(5) 프론트 페이지 설정 views/todo.ejs, public/
총 디렉토리 구조
Todo
└ node_modules
└ [모듈들]
└ controllers ---------------------서비스 영역
└ todo.js
└ models -------------------------DB 스키마 영역
└ todoTask.js
└ public ---------------------------정적 파일 영역
└ fonts
└ images
└ stylesheets
└ routes ---------------------------라우터 영역
└ index.js
└ todo.js
└ views ----------------------------웹 페이지 영역
└ todo.ejs
└ todo-edit.ejs
└ app.js ----------------------------메인 서버 (실제 구동되는 파일)
└ package.json -------------------설정