본문 바로가기

과거공부모음

나의 개발일지 TIL(Today I learned) - express.js와 mongoDB를 이용해 게시판 api 만들고 aws에 배포 개인과제!!

Today I learned

  • 개인과제!

개인과제를 보고 코드를 바로 치는 것보다 간단하게 구상을 하는 습관을 만들기 위해서 S.A를 작성해 보았다

 

프로젝트 명: Board

 

간단 설명: 게시판을 만드는 프로젝트

 

👀요구 기능

  • 게시글(CRUD): 게시글 목록, 게시글 작성, 게시글 조회, 게시글 수정, 게시글 삭제
    • 게시글 목록: 제목, 작성자명, 작성 날짜 조회, 작성 날짜 기준으로 내림차순
    • 게시글 작성: 제목, 작성자명, 비밀번호, 작성 내용 입력해서 저장
    • 게시글 조회: 제목, 작성자명, 작성 날짜, 작성 내용 조회
    • 게시글 수정: 비밀번호를 받아 확인 후 수정
    • 게시글 삭제: 비밀번호를 받아 확인 후 삭제
  • 댓글(CRUD): 댓글 목록, 댓글 작성, 댓글 수정, 댓글 삭제
    • 댓글 목록: 조회하는 게시글에 작성된 댓글 목록, 작성 날짜 기준 내림차순 정렬
    • 댓글 작성: 댓글 내용을 비워둔 댓글은 내용을 입력해달라는 메시지 반환
    • 댓글 수정: 비밀번호 확인 후 수정, 댓글 내용을 비워둔 댓글은 내용을 입력해달라는 메시지 반환
    • 댓글 삭제: 비밀번호 확인 후 삭제
  • aws 배포
    • Ubuntu EC2 노드 포트(3000)을 80번 포트로 포워딩해서 포트 번호 없이 서비스 접속 가능
    • mongoDB를 EC2 내부에 설치해서 연결

⚒️사용 기술

node.js, express.js, mongodb, aws ec2

 

api

간단하지만 S.A를 작성하고 개발을 진행하니 중간중간 S.A를 참고해서 개발을 진행하니 확실하게 그냥 코드를 먼저 짜는 것보다 수월하게 작업이 진행되는 것을 느꼈다

개인과제의 기본 폴더 구조는 아래와 같이 진행했다

project
	-routes
		-comments.js
		-posts.js

	-schema
		-index.js
		-comment.js
		-post.js

	-utills
		-date.js

	-app.js

api관련 기능은 routes안에 분리해서 관리하고 데이터베이스 관련된 기능은 schema로 분리하고 따로 내가 필요해서 만든 유틸성 기능은 utills파일 안에 분리해서 관리하기 편하게 폴더 구조를 진행했다

 

 

데이터베이스 컬렉션 관계형성

MySQL로 진행을 할 때 게시글과 댓글의 관계를 FOREIGN KEY를 이용해 관계를 형성하고 LEFT JOIN을 이용해서 활용을 했다

MongoDB로도 관계를 형성시키고 사용하고 싶었다 MongoDB를 node.js에서 사용할 수 있게 해주는 mongoose에서 populate메서드를 사용해서 어느 정도 구현할 수 있었다

mongoose로 스키마(컬렉션)를 정의할 때 미리 관계 설정을 해줄 수 있다

type으로 데이터 타입 말고 MongoDB ID인 ObjectId를 기재해주면서

ref 속성으로 관계를 형성할 스키마를 명시해두면 populate 메서드를 통해서 관계 형성을 할 수 있다

// node.js에서 mongoDB를 사용할 수 있게 npm으로 설치한 mongoose를 가져온다
const mongoose = require("mongoose");

// mongoose를 이용해서 comment 스카마를 생성한다 이 건 collections이라고 생각하자
const commentSchema = new mongoose.Schema({
    user: {
        type: String,
        required: true,
    },
    password: {
        type: Number,
        required: true
    },
    comment: {
        type: String,
        required: true
    },
    date: {
        type: String,
        required: true
    },
    post: {
        type: mongoose.Schema.Types.ObjectId,
        required: true,
        ref: "Post"
    }
});

// 만든 스키마를 모델로 감싸 객체로 exports를 사용해 내보내서 DB에 실제로 작업한다
module.exports = mongoose.model("Comment", commentSchema);

 

Comment스키마(컬렉션)에 데이터를 추가하고 게시글의 스키마 ID를 가지고 Comment에서 쿼리를 실행한 결과에 게시글의 스키마 ID에 populate를 설정해주면 ObjectId인 필드 값을 실제 post 임베디드 다큐먼트로 매핑해준다

router.post("/comments/:post_id", async (req, res) => {
    try {
        // URL의 파라미터 값을 가져온다 객체 구조분해를 사용
        const { post_id } = req.params;
        // JSON형태의 request를 객체 구조분해를 사용해 각 변수에 넣는다
        const { user, password, comment } = req.body

        // 데이터가 이상하면 강제로 예외를 발생시킨다
        if (!password || !user || !comment) {
            throw e;
        }

        // 입력받은 값을 comment 컬렉션에 추가하고 추가한 스키마? 문서?를 변수에 담는다
        const post_comment = await Comment.create({ post: post_id, user: user, password: password, comment: comment, date: dateFormat(new Date()) });
        // populate를 통해서 post컬렉션과 연결시킨다
        await Comment.populate(post_comment, { path: "post_id" });

        // 정상적으로 데이터베이스에 추가를 한다면 상태코드 200과 성공 메시지를 반환한다
        res.status(200).json({ msg: "댓글을 작성했습니다." });
    } catch {
        // try catch를 통해서 파리미터나 request 데이터가 문제가 있다면 상태코드 400과 실패 메시지를 반환한다
        res.status(400).json({ msg: "데이터 형식이 올바르지 않습니다." });
    }
});

 

시간 Format 정해주기 new Date()를 통해서 게시글이나 댓글을 작성할 때 시간을 추가해주고 싶었다 new Date() 그냥 넣었을 때 가독성이 매우 부족해서 보기 좋은 format으로 시간을 표시해주는 유틸성 기능을 만들어 시간을 처리했다

// 02 03 12 이런식으로 정렬을 위해 두자리 수로 통일해주기 위해 한자리 수 숫자를 체크에 앞에 0을 붙여준다
function Single_digit_check(date) {
    if (date < 10) {
        return "0" + date;
    } else {
        return date;
    }
}

// 시간을 2022년12월15일20시07분00초의 포맷으로 바꾸는 기능
function dateFormat(date) {
    // new Date()로 시간을 만들면 요일부분이 숫자로 나와서 해당하는 인덱스의 요일을 뽑을 수 있게 요일 리스트를 준비
    const day = ['일', '월', '화', '수', '목', '금', '토'];

    // Date() 객체에서 제공하는 메서드를 이용해서 각 해당하는 값을 뽑아와 문자열로 합친다
    // 월부분은 1씩 부족하게 나오기 때문에 +1을 해서 월을 맞춘다
    const dateFormat = date.getFullYear() + "년" + Single_digit_check(date.getMonth() + 1) + "월"
        + Single_digit_check(date.getDate()) + "일" + day[date.getDay()] + "요일"
        + Single_digit_check(date.getHours()) + "시" + Single_digit_check(date.getMinutes()) + "분"
        + Single_digit_check(date.getSeconds()) + "초";

    // 만든 날짜의 문자열을 반환해준다
    return dateFormat;
}

module.exports = dateFormat;

 

AWS배포

AWS를 작업하기 전에 해킹이 너무 무서웠다 그래서 멀티팩터 인증을 걸고 AWS 작업을 진행했다 프리티어로 인스턴스를 만들고 인증키를 가지고 gitBash를 이용해서 ssh -i key 사용자@주소를 이용해서 서버에 접속했다 작은 콘솔 창이 클라우드 컴퓨터를 조작할 수 있는 게 신기했다 node.js와 mongoDB를 설치하고 github에 올려둔 나의 프로젝트를 클라우드 컴퓨터에 설치를 했다 package.json에 있는 모듈을 다운로드하기 위해서 npm install을 해주면 세팅이 끝났다 pm2를 설치하고 pm2 start app.js를 입력하니 내 개인과제가 로컬이 아닌 다른 환경에서 실행이 되었다 👀