엘리스 32일차 화요일 온라인강의 Express.js+MongoDB 웹서비스 만들기 1

치즈말랑이·2022년 5월 17일
0

엘리스

목록 보기
33/47
post-thumbnail
post-custom-banner

01

redirect

router.get('/', (req, res) => {
  // res.render('index');
  res.redirect('/posts');
});

게시글 목록 READ

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

게시글 보기 READ

router.get('/:shortId', async (req, res, next) => {
  const { shortId } = req.params;
  // shortId 로 게시글 찾기
  const post = await Post.findOne({shortId}).exec();
  
  res.render('post/view', { post });
});

게시글 생성 CREATE

router.post('/', async (req, res, next) => {
  const { title, content } = req.body;
  
  try {
    if (!title || !content) {
      throw new Error('제목과 내용을 입력해 주세요');
    }
    // 게시글 생성
    const post = await Post.create({
        title,
        content,
    });
    res.redirect(`/posts/${post.shortId}`);
  } catch (err) {
    next(err);
  }
});

게시글 수정 UPDATE

router.post('/:shortId', async (req, res, next) => {
  const { shortId } = req.params;
  const { title, content } = req.body;
  
  try {
    if (!title || !content) {
      throw new Error('제목과 내용을 입력해 주세요');
    }
    
    // shortId 로 게시글 수정
    await Post.update({shortId}, {
        title, content
    });
    
    res.redirect(`/posts/${shortId}`);
  } catch (err) {
    next(err);
  }
});

게시글 삭제 DELETE

router.delete('/:shortId', async (req, res, next) => {
  const { shortId } = req.params;
  // shortId 로 게시글 삭제
  await Post.deleteOne({shortId});
  res.send('OK');
});

Async Request Handler

utils/async-handlers

module.exports = (requestHandler) => {
  return async (req, res, next) => {
    try {
        await requestHandler(req, res);
    } catch(e) {
        next(e);
    }
  }
}

routes/posts.js

router.get('/', asyncHandler (async (req, res) => {  
  const posts = await Post.find({});
  
  res.render('post/list', { posts });
}));

request handler를 asyncHandler 안에 넣어 그 안에서 try catch로 에러를 거른다음 진행하는것이다.
이렇게하면 라우팅에서 에러를 잡을 필요가 없다.

Pagination

router.get('/', asyncHandler(async (req, res) => {
  if (req.query.write) {
    res.render('post/edit');
    return;
  }
  // url 쿼리에서 page 받기, 기본값 1
  const page = Number(req.query.page || 1);
  // url 쿼리에서 perPage 받기, 기본값 10
  const perPage = Number(req.query.perPage || 10);
  // 전체 게시글 수 쿼리하기
  
  // total, posts 를 Promise.all 을 사용해 동시에 호출하기
    const [total, posts] = await Promise.all([
        Post.countDocuments({}),
        Post
            .find({})
            .sort({createdAt: -1})
            .skip(perPage * (page - 1))
            .limit(perPage)
    ]);
  const totalPage = Math.ceil(total / perPage);
  
  res.render('post/list', { posts, page, perPage, totalPage });
}));

이 코드는 쿼리로 한페이지에 표시되는 게시글 개수와 페이지넘버를 받고있어서 쿼리에서 불러오는데,
처음 접속하면 1페이지인데 그때는 쿼리값이 없으므로 디폴트값을 지정해준다.

sort는 생성일자를 역순으로 정렬, skip은 perPage만큼의 게시글 개수를 skip하고 표시, limit는 perPage만큼의개수만 표시 이다.
total과 posts는 각각 독립적으로 작동하는것이라서 promise.all을 사용한다

profile
공부일기
post-custom-banner

0개의 댓글