본문 바로가기
띡딱똑띡 개발자 Hanna

NodeJS와 MongoDB로 SNS 만들어보기 - user_posting (게시글 라우터)

by HannaDev 2019. 11. 14.

2019/11/14 - [띡딱똑띡 개발자 Hanna] - NodeJS와 MongoDB로 SNS 만들어보기 - user_follow (팔로우 라우터)

 

NodeJS와 MongoDB로 SNS 만들어보기 - user_follow (팔로우 라우터)

2019/11/14 - [띡딱똑띡 개발자 Hanna] - NodeJS와 MongoDB로 SNS 만들어보기 - user_profile (프로필 라우터) ㄴ 이전 글 * 현재까지 설명한 router => 7번 (user_passport), 10번 (user_profile) * 현재 설명하..

granora2019.tistory.com

ㄴ 이전 글

 

 


 

routes 폴더 구조


 

 

* 현재까지 설명한 router => 7번 (user_passport), 10번 (user_profile), 4번 (user_follow)

 

* 현재 설명하고자 하는 router => 8번 (user_posting)

 

 

 

> user_posting

 

user_posting.js 파일 내의 라우터 목록

 

user_posting.js는 게시글 관련 라우터들을 정의한 파일입니다.

+ 4번 게시글 비공개 설정 변경 라우터를 추가하였습니다. (11/15)

나의 비공개 게시물은 내 게시글 목록에서만 보이게 됩니다.

 

1번과 2번을 보면 게시글 목록을 불러온다는 점에서는 같지만

1번은 page, lastDate를 파라미터로 하여 POST요청을 받고

2번은 page를 파라미터로 하여 GET요청을 받습니다.

 

이 두 라우터를 굳이 다른 방식으로 구현할 필요는 없지만

1번을 1번과 같이 구현하고, 2번은 2번같이 구현해도 되겠다고 판단한 이유는

'목록에 추가되는 새로운 게시글'의 존재 여부가 서로 다르다고 판단했기 때문입니다.

 

 

 

1번같은 경우는 '모든 게시글'을 대상으로 최신순으로 목록을 불러오는 라우터입니다.

이 경우 단순 page 번호에 따라 skip, limit을 정해버리면 목록을 조회하는 도중

다른 유저가 새로운 게시글을 올릴 시 '밀림 현상'이 발생할 여지가 있습니다.

 

" 1페이지 조회 => 1페이지 끄트머리 게시글이 새로운 게시글에 밀리면서 2페이지로 이동

=> 2페이지 조회 " --- 이런 경우 2페이지 조회 시 1페이지에서 조회됐던 게시글이 중복해서

뜨게됩니다. 스크롤링이 아닌 페이지에 따라 한페이지씩 보는 구조라면 불편할 수는 있더라도

화면 구조상 이상하지는 않지만, 스크롤링의 경우 그 전페이지 아래에 다음페이지가 붙기 때문에

해당 '밀림 현상'이 발생할 경우 화면이 매우 이상해집니다.

 

하지만 2번같은 경우에는 내가 작성한 글을 보는 와중 '또다른 나'(=다중 접속)가 글을

작성하는 경우는 드물 것이기에 1번과 같은 경우가 거의 발생하지 않을 것입니다.

 

 

 

따라서 '스크롤링'에 따른 목록 조회 시 밀림 현상으로 인한 중복 조회가

발생할 가능성이 있는지 여부에 따라 구현을 달리했습니다.

(근데 사실 그냥 1번방법으로 통일해도 됐을 것 같은ㄷ...)

 

lastDate파라미터를 받을 때는 해당 날짜보다 전에 만들어진 정보를 불러오는 방식으로

단순히 위에서부터 n번째 정보를 받아오는 방식을 피함으로써 밀림 현상으로 인한 중복 조회를 방지합니다.

(= 스크롤링인데 중복 조회되면 화면이 매우 이상해지기 때문에 이런 구조 사용)

 

 

 

(왼) lastDate 파라미터 사용                  (오) 단순 page 조회 방식

 

ㄴ Mongoose 함수에 대해서는 라우터 설명이 끝나면 따로 포스팅을 하도록 하겠습니다.

    (근데 라우터 설명이 써도 써도 끝이 안난다...)

 


5번 게시글 삭제 라우터의 경우 여러가지 함수들을 거칩니다.

 

 

function_posting.js 파일 내 게시글 삭제 함수 (6-1 ~ 6-3)

 

1. 로그인 여부 체크

2. 로그인 상태라면 게시글 작성자 _id와 현재 유저의 _id 비교

   (자신이 작성한 글만 삭제시켜야하니까)

3. 일치하면 게시글 삭제 진행

  3-1. 소속 대댓글 삭제

  3-2. 소속 댓글 삭제

  3-3. 해당 게시글 조회 => 해당 게시글 정보를 토대로 RemovedPost 게시판에 해당 게시글 생성

  3-4. 해당 게시글 삭제

  3-5. 소속 대댓글 좋아요 삭제

  3-6. 소속 댓글 좋아요 삭제

  3-7. 해당 게시글 좋아요 삭제

  3-8. 해당 게시글 대상 북마크가 있다면 북마크의 isRemovedPost 값을 true로 설정

        ㄴ 기획 상 북마크된 게시글이 삭제되었을시,

            북마크 목록에서 누구의 게시글인지정도는 보여주면서

            "삭제된 게시글입니다." 문구 띄우기로 했기 때문.

4. 게시글 삭제 후, 현재 유저의 board_count 감소

 

 


 

 

* Router 상세 정보 *

더보기

POST    /getPosts

* 게시글 목록 (최신순 - 작성일을 기준으로)

* 페이지당 최대 20개씩 받아옴.

 

>> 필요 파라미터 <<

{

  page: 페이지 번호 (int),

  ㄴ 첫번째 페이지일 경우 1로 보내주시면 됩니다.

  ㄴ 실질 라우터 처리에서는 1인지 아닌지 여부만 체크합니다.

      (skip관련 처리 때문에)

  lastDate: 목록 마지막의 created_at (String)

  ㄴ 첫번째 페이지일 경우 0으로 보내주시면 됩니다.

  ㄴ POST 결과값으로 보내는 newLastDate을 다음 페이지

      조회 시 lastDate 파라미터로 설정해 주세요.

}

 

 

> 에러 발생 시

{

  isGetPost: false (boolean),

  errorMsg: 에러 메세지 (String)

}

 

> 정상 작동 시

{

  isGetPost: true (boolean),

  posts: [ { _id: 게시글의 ObjectId (String),

            w_id: 작성자의 ObjectId (String),

            w_nickname: 작성자의 닉네임 (String),

            w_userName: 작성자의 아이디 (String),

            w_isBasicImg: 작성자의 프로필 이미지가 기본 프로필 이미지인지 (boolean),

            w_cloudUrl: 작성자의 프로필 이미지 Url, 기본 프로필 이미지면 null값 (String),

            like_count: 게시글에 눌린 좋아요 수 (int),

            comment_count: 게시글에 달린 코멘트(댓글+대댓글) 수 (int),

            title: 게시글의 제목 (String),

            text: 게시글의 내용 (String),

            created_at: 게시글의 작성일 (String),

            isLike: 로그인되어있을시, 해당 게시글 좋아요 여부 (boolean),

            isClip: 로그인되어있을시, 해당 게시글 북마크 여부 (boolean),

           } ], <= 게시글 목록 리스트 (로그인 안되어있을시, isLike=isClip=false)

  remainPage: 남은 페이지 수 (int),

  totalNum: 남은 목록 수 (int)

  ㄴ totalNum값이 0이면 더이상 조회할 데이터가 없는 상태인 것입니다.

}

 

 

 

 

 

GET    /getMyPosts/:page

* 내 게시글 목록 (최신순 - 작성일을 기준으로)

* 페이지당 최대 20개씩 받아옴.

 

>> 필요 파라미터 (링크 뒤에 붙여서 보내주세요!) <<

{

  page: 페이지 번호 (int),

  ㄴ 조회할 페이지 번호

}

 

 

> 에러 발생 시

{

  isGetPost: false (boolean),

  errorMsg: 에러 메세지 (String)

}

 

> 정상 작동 시

{

  isGetPost: true (boolean),

  posts: [ { _id: 게시글의 ObjectId (String),

              like_count: 게시글에 눌린 좋아요 수 (int),

              comment_count: 게시글에 달린 코멘트(댓글+대댓글) 수 (int),

              title: 게시글의 제목 (String),

              text: 게시글의 내용 (String),

              created_at: 게시글의 작성일 (String),

              isLike: 로그인되어있을시, 해당 게시글 좋아요 여부 (boolean),

              isClip: 로그인되어있을시, 해당 게시글 북마크 여부 (boolean),

           } ], <= 게시글 목록 리스트 (로그인 안되어있을시, isLike=isClip=false)

  user: { _id: 나의 ObjectId (String),

          userName: 나의 아이디 (String),

          nickname: 나의 닉네임 (String),

          isBasicImg: 기본 프로필 이미지 여부 (boolean),

          cloudUrl: 프로필 이미지 Url, 기본 프로필 이미지면 null (String)

         } <= 리스트 아닙니다! 그냥 구조체 하나에요.

  page: 현재 페이지 번호 (int),

  maxPage: 마지막 페이지 번호 (int),

  totalNum: 총 작성 게시글 수 (int)

}

 

 

 

 

 

GET     /getPost/:postId

* 해당 게시글 상세 조회

 

>> 필요 파라미터 (링크 뒤에 붙여 보내기!) <<

{

  postId: 조회하고자 하는 게시글의 ObjectId (String)

}

 

> 에러 발생 시

{

  isGetPost: false (boolean),

  errorMsg: 에러 메세지 (String)

}

 

> 정상 작동 시

{

  isGetPost: true (boolean),

  post: { _id: 게시글의 ObjectId (String),

           w_id: 작성자의 ObjectId (String),

           w_nickname: 작성자의 닉네임 (String),

           w_userName: 작성자의 아이디 (String),

           w_isBasicImg: 작성자의 프로필 이미지가 기본 프로필 이미지인지 (boolean),

           w_cloudUrl: 작성자의 프로필 이미지 Url, 기본 프로필 이미지면 null값 (String),

           like_count: 게시글에 눌린 좋아요 수 (int),

           comment_count: 게시글에 달린 코멘트(댓글+대댓글) 수 (int),

           title: 게시글의 제목 (String),

           text: 게시글의 내용 (String),

           created_at: 게시글의 작성일 (String),

           isLike: 로그인되어있을시, 해당 게시글 좋아요 여부 (boolean),

           isClip: 로그인되어있을시, 해당 게시글 북마크 여부 (boolean),

           isMyPost: 로그인되어있을시, 해당 게시글이 내 게시글인지 여부 (boolean),

          }, <= 게시글 하나, 리스트 아님! (로그인 안되어있을시, isLike=isClip=isMyPost=false)

}

 

 

 

 

 

 

GET      /flipPostPrivate/:postId/:isPrivate

* 게시글 비공개 상태 변경

 

>> 필요 파라미터 (링크 뒤에 붙여 보내기!) <<

{

  postId: 해당 게시글의 ObjectId (String),

  isPrivate: 1이면 비공개 설정, 0이면 공개 설정 (int)

}

 

> 에러 발생 시

{

  isSetPost: false (boolean),

  errorMsg: 에러 메세지 (String)

}

 

> 정상 작동 시

{

  isSetPost: true (boolean),

  isPrivate: 최종 공개/비공개 상태 (boolean)

}

 

 

 

 

 

GET      /removePost/:postId

* 게시글 삭제

 

>> 필요 파라미터 (링크 뒤에 붙여 보내기!) <<

{

  postId: 삭제하고자 하는 게시글의 ObjectId (String)

}

 

> 에러 발생 시

{

  isDeletePost: false (boolean),

  errorMsg: 에러 메세지 (String)

}

 

> 정상 작동 시

{

  isDeletePost: true (boolean)

}

 

ㄴ 프론트(Flutter)를 위한 라우터 상세 정보 입니다.

 

 

 

 

 

 

 

 

 

 

댓글