Board.js 에 MDB 모듈 불러오기
접속 주소 uri 설정
URI vs URL
URL(Uniform Resource Location) : 집 주소 까지만 알려줌
URI (Uniform Resource Identifier) : 집 주소 + 그 집에 사는 누구 까지 표시
DB 에 접속이 된 이후, DB 데이터를 처리 할 수 있으므로, MDB 모듈 MongoClient 의 connect 함수의 콜백으로 기능을 구현!
접속이 완료 되면 2nd 매개 변수로 커서를 받고 해당 커서를 통해 DB, Collection 에 접속
// @ts-check
const express = require('express');
// express에서 제공하는 Router를 변수에 담기
const router = express.Router();
const { MongoClient, ServerApiVersion } = require('mongodb');
const { resolveTypeReferenceDirective } = require('typescript');
const uri =
'mongodb+srv://suji:mtn191371wl@cluster0.s7lxybo.mongodb.net/?retryWrites=true&w=majority';
/* 글 전체 목록 보여주기 */
router.get('/', (req, res) => {
// 데이터 통신이 성공하면 db로 실패하면 err 메세지
// db는 mongodb에서 생성한 모든 데이터를 의미한다.
MongoClient.connect(uri, (err, db) => {
const data = db.db('kdt1').collection('board');
// db에서 데이터를 다 받아온 다음에 article이라는 변수에 넣어준다.
data.find({}).toArray((err, result) => {
const ARTICLE = result;
const articleLen = ARTICLE.length; // ARticle 배열의 길이 전달
// 특정 뷰(ejs 확장자 생략) 파일을 그려라 명령
// obj의 키 값이 ejs의 파일과 동일한지 확인해야 함.
// render는 경로 이동으로 '/' 없어도 되지만, redirect는 /있어야 한다.
res.render('tetz_board', { ARTICLE, articleCounts: articleLen });
});
});
});
/* 글 쓰기 모드로 이동 */
router.get('/write', (req, res) => {
res.render('tetz_board_write');
});
/* 글 추가 기능 수행 */
router.post('/write', (req, res) => {
if (req.body.title && req.body.content) {
// 실질적으로 실행할 코드: 배열 마지막에 글이 추가되는 구조 push
// 키 값으로 title과 content를 가진 객체 = ejs의 name을 따라간다.
const newArticle = {
title: req.body.title,
content: req.body.content,
};
// 통신이 성공하거나 실패하던 이 콜백을 실행해라~
MongoClient.connect(uri, (err, db) => {
const data = db.db('kdt1').collection('board');
// data insertOne추가한다~(배열, 콜백함수)
data.insertOne(newArticle, (err, result) => {
res.redirect('/tetz_board');
});
});
} else {
// 예외 처리: 프론트에서 required로 예외처리해서 실은 안해도 된다.
const err = new Error('데이터가 없습니다');
// @ts-ignore
err.statusCode = 404;
throw err;
}
});
/* 글 수정모드로 이동 */
router.get('/modify/title/:title', (req, res) => {
// db 접속
MongoClient.connect(uri, (err, db) => {
const data = db.db('kdt1').collection('board');
// title이 동일한 게있으면 result에 obj형태로 담아주세요~
data.findOne({ title: req.params.title }, (err, result) => {
if (err) {
throw err;
} else {
// err가 아니라면 selectedArticle에 result를 담아서 하세요!
const selectedArticle = result;
res.render('tetz_board_modify', { selectedArticle });
}
});
});
});
/* 글 수정 기능 수행: 수정하기 눌렀을 때 */
router.post('/modify/title/:title', (req, res) => {
if (req.body.title && req.body.content) {
MongoClient.connect(uri, (err, db) => {
const data = db.db('kdt1').collection('board');
// 수정은 updateOne 메소드 사용: 조건을 주고, 조건을 찾아와서 $set변경해준다.
data.updateOne(
{ title: req.params.title },
{
$set: {
title: req.body.title,
content: req.body.content,
},
},
(err, result) => {
if (err) {
throw err;
} else {
res.redirect('/tetz_board');
}
}
);
});
} else {
const err = new Error('요청 값이 없습니다.');
err.statusCode = 404;
throw err;
}
});
/* 글 삭제 기능 수행 */
router.delete('/delete/title/:title', (req, res) => {
MongoClient.connect(uri, (err, db) => {
const data = db.db('kdt1').collection('board');
// 지우는 것 deletOne 메소드: 찾아준 후 바로 지워준다.
data.deleteOne({ title: req.params.title }, (err, result) => {
if (err) {
throw err;
} else {
// 여기에 redirect 걸면 delete 메소드로 튀어나가기 때문에 notfound가뜬다. => 프론트를 믿고.. send로 처리
res.send('삭제 완료');
}
});
});
});
module.exports = router;
전체 db를 불러오거나 전체 데이터를 받는 경우에는 cursor(DB에 대한 정보와 위치를 알려주는 데이터) 형태로 받아오기 때문에 await 처리 필요 X
단, cursor 를 데이터화 할 때는 통신이 필요하므로 await 처리
기존 callback 에서 처리하던 부분을 await 뒤에 두어서 자연스럽게 나중에 처리하도록 수정
// @ts-check
const express = require('express');
// express에서 제공하는 Router를 변수에 담기
const router = express.Router();
const mongoClient = require('./mongo');
const { MongoClient, ServerApiVersion } = require('mongodb');
const { resolveTypeReferenceDirective } = require('typescript');
const uri =
'mongodb+srv://suji:mtn191371wl@cluster0.s7lxybo.mongodb.net/?retryWrites=true&w=majority';
/* 글 전체 목록 보여주기 */
router.get('/', async (req, res) => {
// await 붙은 순간은 이전에 다 callback으로 처리한 순간들이다.
const client = await mongoClient.connect();
// 데이터를 변화할 때 콜백을 걸어주면 되는 거니까 위치만 알려주는 정보만 넣어준다.(await 필요없음)
const cursor = client.db('kdt1').collection('board');
// 데이터가 받아지면 ARTICLE로 들어간다.
const ARTICLE = await cursor.find({}).toArray();
const articleLen = ARTICLE.length;
res.render('tetz_board', { ARTICLE, articleCounts: articleLen });
});
/* 글 쓰기 모드로 이동 */
router.get('/write', (req, res) => {
res.render('tetz_board_write');
});
/* 글 추가 기능 수행 */
router.post('/write', async (req, res) => {
if (req.body.title && req.body.content) {
const newArticle = {
title: req.body.title,
content: req.body.content,
};
// client에 접속에 관련된 정보를 가져온다.
const client = await mongoClient.connect();
// 접속을 바탕으로 db와 collection
const cursor = client.db('kdt1').collection('board');
// 데이터받는 시간이 걸리니까 await 걸어서 insertOne 추가
await cursor.insertOne(newArticle);
res.redirect('/tetz_board');
}
});
/* 글 수정모드로 이동 */
router.get('/modify/title/:title', async (req, res) => {
const client = await mongoClient.connect();
const cursor = client.db('kdt1').collection('board');
// title과 params의 타이틀이 동일하다면, 해당 데이터가 selectedArticle이 들어간다.
const selectedArticle = await cursor.findOne({ title: req.params.title });
res.render('tetz_board_modify', { selectedArticle });
});
/* 글 수정 기능 수행: 수정하기 눌렀을 때 */
router.post('/modify/title/:title', async (req, res) => {
if (req.body.title && req.body.content) {
const client = await mongoClient.connect();
const cursor = client.db('kdt1').collection('board');
// title이 params의 title과 같다면,
await cursor.updateOne(
{ title: req.params.title },
// req.body와 동일하게 바꿈
{
$set: {
title: req.body.title,
content: req.body.content,
},
}
);
res.redirect('/tetz_board');
} else {
const err = new Error('요청 값이 없습니다.');
err.statusCode = 404;
throw err;
}
});
/* 글 삭제 기능 수행 */
router.delete('/delete/title/:title', async (req, res) => {
const client = await mongoClient.connect();
const cursor = client.db('kdt1').collection('board');
await cursor.deleteOne({ title: req.params.title });
res.send('삭제 완료');
});
module.exports = router;