[힐링 메시지 게시판에 좋아요 누르기 API]

1. 힐링 메시지 게시판에 좋아요 누르기


게시글의 우측 상단의 좋아요 버튼을 누르는 보편적인 좋아요 기능이다.

프로세스의 논리 구조는 다음과 같다.

  1. 해당 게시글에서 이미 좋아요를 눌렀으면, 좋아요가 취소된다.(DB에서 삭제)
  2. 해당 게시글에서는 좋아요가 처음이면 좋아요가 추가 된다.(DB에서 add)

그리고 최종적으로는 좋아요가 눌린 총합을 게시글의 우측 상단에 조회해준다.

먼저 member 테이블과 healing_message 게시판의 DB 구조는 다음과 같다.

여기서 healing_message 게시판의 좋아요 정보를 저장하는 테이블은
heaglin_message_like 테이블이다.
다른 데이터 테이블과의 연관관계를 따져보고 명령어를 설계해보자.

2. Trouble Solving

구현간 어려움은 없었다.
한번에 성공했다.
다만, 코드의 수가 많아서 시간이 조금 걸릴 수 밖에 없었다.

Controller -> Service -> ServiceImple -> Mapper -> XML 순서대로 프로세스가 진행이 되는데,
하나의 컨트롤러에서 시작했지만,
말단의 Mapper와 Xml에는 각각 4개의 로직이 들어가야 해서 코드를 입력하는 시간이 조금 많았을 뿐이지,
실제 논리적인 난이도는 상당히 낮았다.

3. 구현

3.1 Controller

 /**
     * 힐링 메시지 좋아요 누르기
      * @param request 사용자 요청
     * @param messageId 게시글 고유 번호
     * @return 좋아요 누른 수
     */
    @Operation(summary = " 힐링 메시지에 좋아요 누르기 API ", description = "")
    @PostMapping("/like/{messageId}")
    public ResponseEntity<Long> clickLike(HttpServletRequest request,
                                          @PathVariable("messageId") Long messageId){

        return ResponseEntity.ok(healingMessageService.clickLike(request,messageId));
    }

3.2 Service

3.2.1 Interface

/**
     * 힐링 메시지 좋아요 누르기
     * @param request 사용자 요청
     * @param messageId 게시글 아이디
     * @return 좋아요 누른 수
     */
    Long clickLike(HttpServletRequest request, Long messageId);

[서비스 단에서 인터페이스와 구현체의 분리 설계]

  1. 느슨한 결합 & 코드의 유연성
    구현체에 직접 의존하지 않으므로, 코드의 종속성이 줄어들고 유지보수가 쉬워집니다.

  2. 역할 분리
    인터페이스 = 무엇을 구현할 것인가?
    구현체 = 어떻게 구현할 것인가?

  3. 기획 변경에 대비
    비즈니스 로직이 변동되더라도 interface를 통해 서비스 계층의 기본 계약(Contract)은 유지된다.
    이를 통해 기존 코드를 최소한으로 수정하면서 새로운 요구사항을 반영할 수 있습니다.

3.2.2 Implements

/**
     * 힐링 메시지 좋아요 누르기
     * @param request 사용자 요청
     * @param messageId 게시글 아이디
     * @return 좋아요 누른 수
     */
    @Override
    public Long clickLike(HttpServletRequest request, Long messageId) {

        /* 사용자 고유 번호 조회 */
        Long userNumber = jwtService.extractUserNumberFromRequest(request);

        /* 좋아요 클릭 여부 판단 */
        boolean clickStatus = healingMessageMapper.checkAlreadyCliked(messageId,userNumber);
        log.info("clickStatus {} ", clickStatus);

        /*
        * 1. 이미 좋아요를 눌렀으면 , 좋아요 취소
        * 2. 좋아요가 기록이 없으면 , 좋아요 승인
        * */
        if(clickStatus){
            healingMessageMapper.deleteLike(messageId,userNumber);
            log.info("좋아요 삭제");
        }else{
            healingMessageMapper.permitLike(messageId,userNumber);
            log.info("좋아요 추가");
        }

        /* 좋아요 총량 합산 */
        Long likeCount = healingMessageMapper.getLikeCount(messageId);
        log.info("like Count {}",likeCount);

        return likeCount;
    }

사용자의 고유번호 + 게시글의 고유번호를 주된 매개변수로 사용을 한다.

먼저 좋아요가 기존에 클릭되었는지를 조회하고,
참 & 거짓값에 따라서 if 문으로 다음 로직은 실행한다.

  1. 이미 좋아요를 눌렀으면 , 좋아요 취소

  2. 좋아요가 기록이 없으면 , 좋아요 승인

    모든 연산이 끝나면 최종적으로 좋아요의 총합을 반환한다.

3.3 Mapper

3.3.1 Mapper

/**
     * 동일한 messageId,userNumber 데이터가 있는지 확인
     * @param messageId 메시지 아이디
     * @param userNumber 사용자 고유 번호
     * @return
     */
    Boolean checkAlreadyCliked(@Param("messageId") Long messageId,
                               @Param("userNumber") Long userNumber);

    /**
     * 좋아요 취소
     * @param messageId 메시지 아이디
     * @param userNumber 사용자 고유 번호
     */
    void deleteLike(@Param("messageId") Long messageId,
                    @Param("userNumber") Long userNumber);

    /**
     * 좋아요 승인
     * @param messageId 메시지 아이디
     * @param userNumber 사용자 고유 번호
     */
    void permitLike(@Param("messageId") Long messageId,
                    @Param("userNumber") Long userNumber);

    /**
     * DB에서 좋아요 총량 조회
     * @param messageId 메시지 아이디
     * @return 총량 반환
     */
    Long getLikeCount(Long messageId);

각 메서드는 최대한 본연이 역할을 잘 반영하도록 네이밍을 실시하였다.

3.3.2 Xml

 <!-- 동일한 messageId와 userNumber 데이터 확인 -->
    <select id="checkAlreadyCliked" resultType="boolean">

        SELECT
            IF(COUNT(*) > 0, TRUE, FALSE)
        FROM
            healing_message_like
        WHERE
            messageId = #{messageId} AND userNumber = #{userNumber}

    </select>

    <!-- 좋아요 취소 -->
    <delete id="deleteLike">
        DELETE

        FROM
            healing_message_like
        WHERE
            messageId = #{messageId} AND userNumber = #{userNumber}
    </delete>

    <!-- 좋아요 승인 -->
    <insert id="permitLike">
        INSERT INTO healing_message_like (messageId,userNumber)
        VALUES (#{messageId}, #{userNumber})
    </insert>

    <!-- DB에서 좋아요 총량 조회 -->
    <select id="getLikeCount" resultType="java.lang.Long">
        SELECT
            COUNT(*)
        FROM
            healing_message_like
        WHERE
            messageId = #{messageId}
    </select>

4. 결과

200ok 성공 메시지와
좋아요를 누른 합산 = 1이 출력되었다.

아래 사진은 로그 기록이다.
한줄한줄 차례대로 설명하면,
1. 이전에 클릭 여부 = false (이번에 처음 누름)
2. 좋아요 추가 메서드 실행
3. 좋아요 총 합산 값 = 1

profile
내가 있는 그 조직에서 가장 성실하기만 하자

0개의 댓글