Latte 개발일지 : 5. Post List, Post Search 개발

이동건·2021년 8월 25일
1

Latte

목록 보기
5/9
post-thumbnail

우선 포스트 리스트를 불러올 수 있도록 Post List 화면을 개발한다.

이 부분은 Home 화면의 중하단 부분과 비슷한 형태를 띄고 있다.
Home 화면의 중하단은 우선 Post List를 만든 후에 비슷하게 개발할 예정이다.

요구사항 분석은 Home 화면과 비슷하다.

Post List를 가져온다.

  • Question과 Community를 판별하여 가져온다.
  • Post는 7개를 가져온다.
  • Post에 대한 Hashtag를 가져온다.
  • 제목을 가져온다.
  • 내용을 가져온다.
  • 작성자를 가져온다.
  • 북마크 수를 가져온다.
    • 북마크 수가 999개 이상이면 999+로 나타낸다.
  • 댓글 수를 가져온다.
    • 댓글 수가 999개 이상이면 999+로 나타낸다.
  • 북마크 여부를 가져온다.
    • 북마크를 안 하고 있다면 책갈피 클릭시 북마크 처리를 한다.
    • 북마크를 하고 있다면 책갈피 클릭시 북마크를 취소한다.

테스트 코드 작성부터 시작하자.

포스트 리스트에 대한 부분을 Page를 이용한 처리를 하였다.
우선 PostListDto부터 제작해준다.

하나의 포스트에서 필요한 내용을 담을 수 있도록 작성하였다.

그럼 이어서 searchPostPage를 만들어주도록 한다.
QueryDsl 사용을 위해 custom 인터페이스와 impl 클래스를 만들어주자.


(PageRequest는 실수라서 추후에 Pageable로 변경해주었다.)

우선 PostSearchCondition부터 제작해 준다.
포스트 리스트에서 걸러내야 할 부분을 생각해보면

  • isDeleted가 0이어야 한다.
  • isQna가 0이어야 한다.
  • 타이틀, 컨텐츠, 코드에서 키워드 검색이 가능해야한다.
  • 북마크수가 많은 것이 popular한 것으로 정의한다.
  • 최신순은 idx값으로 처리한다.

이에 맞춰 PostSearchCondition을 제작했다.

tag에 대한 부분은 아무리 생각해도 repository가 TagRepository를 참조하거나 service를 참조하는 수 밖에 없을 것 같았고, 이는 안티패턴이라고 생각이 들어 아예 다른 쿼리로 빼기로 하였다.

그럼 이어서 Repository 작성을 진행해 본다.

PostListDto에서 요구하는 파라미터인 post, replyCount, bookmarkCount를 넣어주었고 isBookmarked는 서브쿼리를 이용해 유저 아이디와 같은지 판별해 넣어주었다.
reply와 bookmark는 fetchjoin을 이용해 최적화 해 주었으며 where절은 다음과 같이 null이라면 조건을 무시할 수 있도록 구성하였다.

타이틀, 본문, 코드에 대해 키워드를 contains로 검색할 수 있게 하여 like의 %keyword%와 같은 효과를 주었으며 특정 일자 이후로 검색할 수 있도록 dateAfter를 넣었다.

또한 카운트 쿼리를 계산함에 있어 reply와 bookmark join은 필요가 없으므로 조인절을 제외한 countQuery를 새로 작성해 주었다.

여기에서 getPage 안에서 fetchCount를 한 이유는
1. 페이지 시작이면서 컨텐츠 사이즈가 페이지 사이즈보다 작을 때
2. 마지막 페이지 일 때
이 두 경우에 countQuery를 실행하지 않도록 하기 위함이다.

기획 요구사항에 다음의 항목이 있었다.

orderBy를 추가해 간단하게 해결해 주기로 하였다.
PostRepositoryCustom에 메서드 두 개를 추가해 주었다.

우선 최신순부터 진행한다.
사실 id 전략을 auto increament로 설정했기 때문에 그냥 id 내림차순으로 설정하면 된다.

다음처럼 post.id.desc를 추가해 searchPostPageRecent를 추가해주었다.
다음은 searchPostPagePopular를 추가한다.
북마크 개수가 같으면 최신 순으로 정렬을 진행했다.

그럼 테스트로 돌아와 실행해 보자.

야호! 초록불이다.
이어서 search도 잘 동작하는지 확인해 보자.

날짜 이후 검색도 테스트를 만들어 주었다.

search keyword와 날짜 이후 검색도 잘 동작하는 걸 확인할 수 있었다.

이제 프론트가 사용할 수 있도록 controller를 제작해 주자.

http://localhost:8080/api/v1/postList?page=0&size=15&userId=1&isQna=0
다음처럼 요청을 보냈을 때

{
    "content": [
        {
            "postId": 3,
            "userId": 1,
            "userName": "동건",
            "postTitle": "post title",
            "postContent": "post content",
            "replyCount": 0,
            "bookmarkCount": 0,
            "isBookmarked": 0,
            "tagIds": [],
            "tags": []
        },
        {
            "postId": 2,
            "userId": 1,
            "userName": "동건",
            "postTitle": "배고파요",
            "postContent": "배가 고프다. 많이 고프다.",
            "replyCount": 0,
            "bookmarkCount": 0,
            "isBookmarked": 0,
            "tagIds": [],
            "tags": []
        }
    ],
    "pageable": {
        "sort": {
            "unsorted": true,
            "sorted": false,
            "empty": true
        },
        "pageNumber": 0,
        "pageSize": 15,
        "offset": 0,
        "paged": true,
        "unpaged": false
    },
    "totalElements": 2,
    "totalPages": 1,
    "last": true,
    "sort": {
        "unsorted": true,
        "sorted": false,
        "empty": true
    },
    "numberOfElements": 2,
    "number": 0,
    "first": true,
    "size": 15,
    "empty": false
}

잘 반환이 되는 걸 확인할 수 있었다.

이번엔 리스트 화면에서 북마크를 할 수 있도록 북마크를 구현해주자.
우선 테스트코드부터 작성한다.

이어서 service에서 구현해 준다.

테스트역시 성공적으로 통과했다.
그럼 controller에서 api를 만들어준다.


다음과 같이 제작하고 테스트 해 본다.

원하는대로 잘 나타나는 걸 확인할 수 있다.

이어서 인터뷰에서도 적용해 준다. 서비스에 지난번에 만들어놓은 createInterviewBookmark와 createInterviewLike를 사용해준다.

이렇게 포스트 리스트에 대한 구현을 완료했다.

profile
코드를 통한 세계의 창조

0개의 댓글