Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 응원톡 생성 및 리스트 가져오기 API 작성 #199

Merged
merged 9 commits into from
Jan 26, 2023

Conversation

sanbonai06
Copy link
Member

@sanbonai06 sanbonai06 commented Jan 26, 2023

개요

작업사항

  • 응원톡 생성과 리스트 가져오기 API를 작성했습니다.
  • 티켓프로젝트 2022 방식과 다르게 여러 이벤트에 따라 다르게 걸리는 응원톡이라고 판단하여 경로변수를 통해 나누었습니다.
  • 생성 API
POST /v1/event/{eventId}/comments

{
  "success": true,
  "status": 200,
  "data": {
    "id": 65,
    "nickName": "고스락키보드",
    "content": "test",
    "createdAt": "2023-01-26 12:43:53",
    "userInfoVo": {
      "userId": 1,
      "userName": "김민준",
      "email": "sanbonai06@nate.com",
      "phoneNumber": "+82 10-2623-9201",
      "profileImage": "http://k.kakaocdn.net/dn/6FCUN/btrURo6Y2ct/VPwWabivrVD0wkN3bEtZoK/img_640x640.jpg"
    }
  },
  "timeStamp": "2023-01-26T12:43:53.012823"
}
  • 이벤트 경로변수 잘 못 넣었을 때
{
  "success": false,
  "status": 404,
  "code": "Event_404_1",
  "reason": "이벤트를 찾을 수 없습니다.",
  "timeStamp": "2023-01-26T12:50:32.732973",
  "path": "http://localhost:8080/api/v1/event/2/comments"
}
  • 위 밸리데이션과 닉네임 및 내용 길이도 체크해주었습니다.
  • 응원톡 리스트 가져오기 API는 기존 발급 티켓 리스트 가져오기와 다르게 무한스크롤 방식으로 만들었습니다.
  • 처음에는 뱅키즈에 작성했던 것처럼 page로 반환해서 가공하려 했으나 Slice를 사용하는 방식이 더 깔끔하고 QueryDsl과 더 맞다고 생각해 변경했습니다.
public Slice<Comment> searchToPage(CommentCondition commentCondition, Pageable pageable) {
        List<Comment> comments =
                queryFactory
                        .selectFrom(comment)
                        .leftJoin(comment.user, user)
                        .fetchJoin()
                        .where(
                                eventIdEq(commentCondition.getEventId()),
                                lastIdLessThanEqual(commentCondition.getLastId()))
                        .orderBy(comment.id.desc())
                        .limit(pageable.getPageSize() + 1)
                        .fetch();

        return checkLastPage(pageable, comments);
    }

// 다음 페이지의 여부 체크한 뒤 Slice로 반환
private Slice<Comment> checkLastPage(Pageable pageable, List<Comment> comments) {

        boolean hasNext = false;

        if (comments.size() > pageable.getPageSize()) {
            hasNext = true;
            comments.remove(pageable.getPageSize());
        }

        return new SliceImpl<>(comments, pageable, hasNext);
    }
  • 리스트 가져오기 API 성공 시

  • 마지막 페이지일 때

GET /v1/event/{eventId}/comments?lastId=7

 {
  "success": true,
  "status": 200,
  "data": {
    "hasNext": false,
    "comments": [
      {
        "commentInfo": {
          "commentId": 20,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 19,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 18,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 17,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 16,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 15,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 14,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 13,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 12,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 11,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 10,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 9,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 8,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 7,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 6,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 5,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 4,
          "nickName": "고스락키보드",
          "content": "테스트",
          "createdAt": "2023-01-25 00:53",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 3,
          "nickName": "고스락키보드",
          "content": "테스트",
          "createdAt": "2023-01-25 00:52",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 2,
          "nickName": "고스락키보드",
          "content": "테스트",
          "createdAt": "2023-01-25 00:39",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 1,
          "nickName": "고스락키보드",
          "content": "테스트",
          "createdAt": "2023-01-25 00:37",
          "userId": 1
        }
      }
    ]
  },
  "timeStamp": "2023-01-26T20:34:25.389968"
}
  • 다음 페이지가 있을 때
GET /v1/event/{eventId}/comments?lastId=

{
  "success": true,
  "status": 200,
  "data": {
    "hasNext": true,
    "comments": [
      {
        "commentInfo": {
          "commentId": 21,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 20,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 19,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 18,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 17,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 16,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 15,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 14,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 13,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 12,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 11,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 10,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 9,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 8,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 7,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 6,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 5,
          "nickName": "고스락키보드",
          "content": "test",
          "createdAt": "2023-01-25 16:21",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 4,
          "nickName": "고스락키보드",
          "content": "테스트",
          "createdAt": "2023-01-25 00:53",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 3,
          "nickName": "고스락키보드",
          "content": "테스트",
          "createdAt": "2023-01-25 00:52",
          "userId": 1
        }
      },
      {
        "commentInfo": {
          "commentId": 2,
          "nickName": "고스락키보드",
          "content": "테스트",
          "createdAt": "2023-01-25 00:39",
          "userId": 1
        }
      }
    ]
  },
  "timeStamp": "2023-01-26T20:40:15.144012"
}
  • @9yujin 클라이언트 분들은 응답값의 hasNext 컬럼에 따라 다음 요청의 여부를 결정해주시면 됩니다.

  • 추가로 lastId는 해당 응답의 가장 마지막 comment의 id를 보내주시면 됩니다.

  • nest.js 버전과 달라진 것이 있으니 참고하세요

  • 궁금한점: 티켓프로젝트 2차에서 작성한 랜덤 댓글 뽑기 및 댓글 카운트 반환 API도 필요한가요? 아직 해당 화면을 못찾아서 따로 개발은 안해놓았습니다. 필요하면 말씀해주세요

변경로직

  • 내용을 적어주세요.

@sanbonai06 sanbonai06 added the For: API [이슈 대상] 외부 API label Jan 26, 2023
@sanbonai06 sanbonai06 self-assigned this Jan 26, 2023
Copy link
Member

@gengminy gengminy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쿼리 DSL 적용 고생 많으셨습니다 👍

Comment on lines 22 to 26
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "yyyy-MM-dd HH:mm:ss",
timezone = "Asia/Seoul")
private final LocalDateTime createdAt;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DateFormat ....!!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그 궁금한게 있었는데 저렇게 jsonFormat으로 엮는거랑 정확한 차이가 궁금했습니당 @gengminy

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그 궁금한게 있었는데 저렇게 jsonFormat으로 엮는거랑 정확한 차이가 궁금했습니당 @gengminy

4줄짜리 1줄로 줄여서 깔끔하게 만들어줘요 기능은 똑같애요

Copy link
Member

@ImNM ImNM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굿!
그 원랜 호스트 마다 응원톡 생기긴하는데.
그냥 공연마다로 바꿔도 될것 같아요..!

public static RetrieveCommentDTO of(Comment comment, User user) {
return RetrieveCommentDTO.builder()
.commentInfo(comment.toCommentInfoVo())
.userInfo(user.toUserInfoVo())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

티켓 예매관리나 관리자쪽에서는 ( 호스트에게 노출되는 환경 )
전화번호 까지 주는게 괜찮은것 같긴한데,
응원톡( 여러 사용자들에게 노출되는 환경에 )
전화번호 까지 주는건 무리가 있지않나 싶긴하네유..
따로 publicUserInfo 처럼 만들어야할듯 해요

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

응원톡 리스트를 가져가는데 굳이 user의 모든 정보를 줘야할까? 고민해서 처음에는 userId만 넘기는 식으로 생각해봤었어요. 이런 방식으로 가면 좀 이상할까요?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그러게요 그냥 닉네임 정보받은거 내려주는게 맞지 않나 싶음

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

본인 글은 오른쪽에 떠야하는걸로 봐서 유저 정보는 내려주는게 맞지 않을까용

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sanbonai06
isMine 같은 dto 필드 만들어서 true false만 내려주심될듯요!

@ImNM
Copy link
Member

ImNM commented Jan 26, 2023

경민형이 UserProfileVo 바로 위 피알에 만들었더라고요!
그거 사용해도 좋을듯~

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 222 Code Smells

12.3% 12.3% Coverage
1.2% 1.2% Duplication

@sanbonai06 sanbonai06 merged commit 5649d1b into dev Jan 26, 2023
@sanbonai06 sanbonai06 deleted the feat/183-talk branch January 26, 2023 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For: API [이슈 대상] 외부 API
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

🚀 [feature] 알림톡 구현
3 participants