Nodejs 게시판 오픈소스 - nodejs gesipan opeunsoseu

[Node.js] 게시판 CRUD 만들기, 게시글 작성/상세/수정/삭제

  • 2021.12.09 00:33
  • 프로그래밍/Node.js

글 작성자: 망고좋아

반응형

Nodejs 게시판 오픈소스 - nodejs gesipan opeunsoseu
🎯 게시판 CRUD 만들기

📝 모델 선언하기

🛠 /models/schemas/post.js

const mongoose = require("mongoose");
const { Schema } = require("mongoose");
const shortId = require("./types/short-id");

module.exports = new Schema(
  {
    shortId,
    title: String,
    content: String,
    author: String,
  },
  {
    timestamps: true,
  }
);

 

🛠 /models/index.js

exports.Post = mongoose.model("Post", PostSchema);
  • MongoDB의 ObjectID는 URL에 사용하기 좋은 값이 아니기 때문에 대체할 수 있는 아이디를 shortId로 생성해준다.
  • 제목, 내용, 작성자를 String 타입으로 스키마에 선언 (회원가입 로그인 후 작성자 연동으로 변경 예정)
  • timestamps 옵션으로 작성 시간, 수정 시간을 자동으로 기록해 준다.

 

📝 shortId

const { nanoid } = require("nanoid");
const shortId = {
  type: String,
  default: () => { // shortId의 값이 전달되지 않았을 때 자동으로 함수를 실행해서 nanoid를 생성해서 shortId를 default으로 지정
    return nanoid();
  },
  require: true,
  index: true,
};
module.exports = shortId;
  • ObjectId를 대체할 shortId 타입을 Mongoose Custom Type으로 선언해준다.
  • 중복 없는 문자열을 생성해 주는 nanoid 패키지 활용
  • default를 이용해 모델 생성 시 자동으로 ObjectId를 대체할 아이디 생성해준다.

 

📝 게시글 작성

📕 게시글 작성 흐름

  1. exports.Post = mongoose.model("Post", PostSchema);
    6 로 작성 페이지 접근
  2. exports.Post = mongoose.model("Post", PostSchema);
    7 이용해 post 요청 전송
  3. exports.Post = mongoose.model("Post", PostSchema);
    8 이용하여 post 요청 처리
  4. exports.Post = mongoose.model("Post", PostSchema);
    9 이용하여 post 완료 처리

 

📕 작성 페이지 만들기

🛠 /routes/posts.js

const { Router } = require("express");

const router = Router();

router.get("/", (req, res, next) => {
  if (req.query.write) {
    res.render("posts/edit"); //req.query.write값이 있다면 posts/edit 템플릿으로 이동
    return;
  }
  ....
});

....
module.exports = router;

 

🛠 /views/posts/edit.pug

form(action="/posts", method="post")
    table
        tbody
            tr
                th 제목
                td: input(type="text" name="title")
            tr
                th 제목
                td: textarea(name="content")
            td
                td(colspan="2")
                    input(type="submit" value="등록")

 

📕 POST 요청 처리하기

const { Post } = require("./models");
...

router.post("/", async (req, res, next) => {
  const { title, content } = req.body;
  try {
        // create 생성
    await Post.create({
      title,
      content,
      author: "DUMMY", // set dummy author before add users
    });
    res.redirect("/"); // 게시글 작성이 완료되면 root path로 이동, posts/post:shortid로 전달하면 작성한 게시글로 이동
  } catch (err) {
    next(err);
  }
});

...

 

📝 게시글 목록 및 상세

📕 게시글 목록 및 상세 흐름

  1. const { nanoid } = require("nanoid");
    const shortId = {
      type: String,
      default: () => { // shortId의 값이 전달되지 않았을 때 자동으로 함수를 실행해서 nanoid를 생성해서 shortId를 default으로 지정
        return nanoid();
      },
      require: true,
      index: true,
    };
    module.exports = shortId;
    0 로 목록 페이지 접근
  2. const { nanoid } = require("nanoid");
    const shortId = {
      type: String,
      default: () => { // shortId의 값이 전달되지 않았을 때 자동으로 함수를 실행해서 nanoid를 생성해서 shortId를 default으로 지정
        return nanoid();
      },
      require: true,
      index: true,
    };
    module.exports = shortId;
    1 이용하여 상세 URL Link
  3. router.get('/:shortId') path parameter 이용하여 요청 처리

 

📕 게시글 목록 구현하기

🛠 /routes/posts.js

router.get("/", async (req, res, next) => { // posts  경로로 접근했을 때
  const posts = await Post.find({}); // 작성된 모든 글 가져오기
  res.render("posts/list", { posts }); //posts/list에 posts 값 전달
});

 

🛠 /view/posts/list.pug

...
table
    tbody
        each post in posts
            tr
                td
                    a(href=`/posts/${post.shortId}`) = post.title // 경로설정
                td= post.author
                td= formatDate(post.createdAt) // formatDate는 따로 추가한 함수이다.
    tfoot
        tr
            td(colspan="3")
                a(href="/posts?write=true") 등록하기

 

📕 formatDate 함수 추가하기

🛠 app.js

const dayjs = require("dayjs");

app.locals.formatDate = (date) => {
  return dayjs(date).format("YYYY-MM-DD HH:mm:ss"); // 특정 포맷으로 변환
};

 

📕 게시글 상세 구현하기

🛠 /routes/posts.js

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 });
});

 

🛠 /views/posts/view.pug

exports.Post = mongoose.model("Post", PostSchema);
0

 

📝 게시글 수정

📕 게시글 수정 흐름

  1. const { nanoid } = require("nanoid");
    const shortId = {
      type: String,
      default: () => { // shortId의 값이 전달되지 않았을 때 자동으로 함수를 실행해서 nanoid를 생성해서 shortId를 default으로 지정
        return nanoid();
      },
      require: true,
      index: true,
    };
    module.exports = shortId;
    2로 수정 페이지 접근
  2. 작성 페이지를 수정 페이지로도 동작하도록 작성
  3. const { nanoid } = require("nanoid");
    const shortId = {
      type: String,
      default: () => { // shortId의 값이 전달되지 않았을 때 자동으로 함수를 실행해서 nanoid를 생성해서 shortId를 default으로 지정
        return nanoid();
      },
      require: true,
      index: true,
    };
    module.exports = shortId;
    3로 post 요청 전송
    • html form은 PUT method를 지원하지 않기 때문에 post 사용

 

📕 수정 페이지 만들기

🛠 /routes/posts.js

exports.Post = mongoose.model("Post", PostSchema);
1

 

🛠 /view/posts/edit.pug

exports.Post = mongoose.model("Post", PostSchema);
2

 

📕 수정 요청 처리하기

exports.Post = mongoose.model("Post", PostSchema);
3

 

📝 게시글 삭제

📕 게시글 삭제 흐름

  1. 게시글 상세 페이지에 삭제 버튼 추가
  2. html form은 DELETE 메서드를 지원하지 않음
  3. JavaScript를 이용해 fetch 함수로 HTTP Delete 요청 전송
  4. router.delete의 응답을 fetch에서 처리

 

📕 HTTP Delete 요청 전송 및 응답 처리

🛠 /posts/view.pug

exports.Post = mongoose.model("Post", PostSchema);
4

 

📕 DELETE 요청 처리하기

🛠 /routes/posts.js

exports.Post = mongoose.model("Post", PostSchema);
5

반응형

공유하기

게시글 관리

구독하기기록의 힘

'프로그래밍 > Node.js' 카테고리의 다른 글

[Node.js] 게시판 페이지네이션 구현하기, Pagination  (0)2021.12.09[Node.js] Async Request Handler  (0)2021.12.09[Node.js] Node.js REST API란?  (0)2021.12.04[Node.js] Node.js Middleware란?  (0)2021.12.04[Node.js] Express.js 동작 방식  (0)2021.12.02

  • 댓글
  • 공유하기
  • 다른 글

댓글

이 댓글의 메뉴 토글

방문자 정보

이름

암호

운영자에게만 공개

작성하기

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Node.js] 게시판 페이지네이션 구현하기, Pagination

    [Node.js] 게시판 페이지네이션 구현하기, Pagination

    2021.12.09

  • [Node.js] Async Request Handler

    [Node.js] Async Request Handler

    2021.12.09

  • [Node.js] Node.js REST API란?

    [Node.js] Node.js REST API란?

    2021.12.04

  • [Node.js] Node.js Middleware란?

    [Node.js] Node.js Middleware란?

    2021.12.04

다른 글 더 둘러보기