[ Node.js ] CRUD 게시판 만들기

김대한·2023년 4월 29일
0

MongoDB-Node.js

목록 보기
3/3

이 글은 충청 ICT이노베이션스퀘어 Web Programming & AI 온라인 교육중 CRUD 게시판 만들기 실습을 하고 정리한 글입니다.

Schema 정의

const mongoose  = require('mongoose');
const shortId = require('../types/short-id');

const PostSchema = new mongoose.Schema({
    shortId,
    title : String,
    content: String,
    author : String,

}, {
    timestamps : true
});

module.exports = PostSchema;

제일 먼저 user가 게시판에 등록할 Data를 정의해준다. ObjectID는 URL에 사용하기에 적합하지 않기에 ShortID를 사용하고 제목, 내용, 작성자를 데이터로 넣어준다. 또한 timestamps 옵션을 통해 작성시간, 수정시간을 자동으로 기록하게 해준다.

const { nanoid } = require('nanoid');

const shortId = {
    type: String,
    default: () => {
        return nanoid();
    },
    require: true,
    index: true,
}

module.exports = shortId;
  • type : 해당 필드를 String 타입으로 지정
  • default : 필드의 기본값을 설정하는데 nanoid()함수를 통해 중복없는 랜덤한 문자열을 생성하여 기본값으로 지정
  • require : 필드의 필수 여부를 지정
  • index : 필드가 인덱스로 설정되어 있는지 여부를 지정

게시글 작성

게시글 작성 흐름

  1. /posts?write=true로 작성페이지 접근
  2. 게시글 작성 후 /posts에 POST 요청 전송
  3. router.post와 mongoose를 이용하여 해당 데이터를 DB에 저장
  4. 본 페이지로 redirect

예시 code

router.get('/', async(req, res, next) => {
    if (req.query.write) {
        res.render('posts/edit');
        return;
    }
    ...
})

GET 요청 들어올시 쿼리에 write파라미터가 있는지 확인 후 있으면 게시글 작성페이지인 /posts/edit 페이지를 전송

router.post('/', async(req, res, next) => {
    const {title, content} = req.body;
    try {
        await Post.create({
            title,
            content,
        });
        res.redirect('/');
    } catch(err) {
        next(err);
    }
});

POST 요청이 들어올시 body 부분의 title, content 값을 가져와서 Document 생성, 그 후에 / 페이지로 리다이렉트

게시글 목록 및 상세

게시글 목록 및 상세 흐름

  1. /posts로 게시글 목록 페이지 접근
  2. 각각의 게시글을 /posts/{shortId} 로 URL Link
  3. 클릭 시 해당 shortid값을 가지고 있는 게시글 상세 페이지로 이동
  4. router.get('/:shortId') path 파라미터를 사용하여 요청 처리

예시 code

router.get('/', async(req, res, next) => {
    if (req.query.write) {
        res.render('posts/edit');
        return;
    }
    // 게시글 목록
    const posts = await Post.find({});
    res.render('posts/list', { posts });
    
})

게시글 목록은 게시글 생성을 처리하는 부분에서 처리한다. write 파라미터가 없이 바로 /posts 로 접근했을시에 모든 데이터를 찾아 /list 페이지에서 보여주도록 한다.

router.get('/:shortId', async (req, res, next) => {
    const { shortId } = req.params;
    const post = await Post.findOne({ shortId });
    if (!post) {
        next(new Error('Post NotFound'));
        return;
    }
    ...
    res.render('posts/view', { post });
}); 

GET 메소드로 /posts/{shortId} 페이지에 접근 했을 시 해당 shortId에 해당되는 값들을 가져와 view 페이지에서 보여주도록한다.

게시글 수정

게시글 수정 흐름

  1. posts/{shortId}?edit=true로 수정 페이지 접근
  2. 작성페이지를 수정페이지로도 동작하도록 작성
  3. 작성 내용을 posts/{shortId}로 post 전송
    (html form은 PUT 메소드를 지원하지 않기에 post 사용)

예시code

router.get('/:shortId', async (req, res, next) => {
    const { shortId } = req.params;
    const post = await Post.findOne({ shortId });
    if (!post) {
        next(new Error('Post NotFound'));
        return;
    }
    # 수정페이지
    if (req.query.edit) {
        res.render('posts/edit', { post });
        return;
    }
    res.render('posts/view', { post });
}); 

쿼리에 edit 파라미터가 존재한다면 posts/edit 페이지에서 글을 다시 작성 가능하도록 처리

router.post('/:shortId', async(req, res, next) => {
    const {shortId} = req.params;
    const {title, content} = req.body;
    
    const post = await Post.findOneAndUpdate({shortId}, {title, content,});
    if (!post){
        next(new Error('Post NotFound'));
        return;
    }
    res.redirect(`/posts/${shortId}`);
});

게시글 데이터를 수정 작성 한 뒤 posts/{shortId}에 POST 요청시 해당 shortId에 해당하는 Document의 데이터를 수정한뒤 상세페이지로 redirect

게시글 삭제

게시글 삭제 흐름

  1. 게시글 상세 페이지에 삭제 버튼 추가
  2. JavaScript를 이용해 fetch함수로 HTTP DELETE 요청 전송
  3. router.delete에서 응답을 fetch에서 처리

예시 code

router.delete('/:shortId', async(req, res, next) => {
    const {shortId} = req.params;
    try {
        await Post.deleteOne({ shortId });
        res.send('OK');

    } catch (err){
        next(err);
    }
});

delete 요청이 오면 해당 document를 삭제 후에 OK를 보냄

자세한 코드는 아래에 링크에 있습니다. https://github.com/dlxla4820/crud_board1/tree/master/express-start2

profile
개발자 지망생 입니다.

0개의 댓글