본문 바로가기
Spring/JPA + Security

[Spring Data JPA] JPA를 사용한 구독하기 3 - 구독하기 로직 구현하기

by pyogowoon 2023. 1. 8.
package com.pyo.pyostagram.web.api;

import com.pyo.pyostagram.config.auth.PrincipalDetails;
import com.pyo.pyostagram.domain.subscribe.Subscribe;
import com.pyo.pyostagram.service.SubscribeService;
import com.pyo.pyostagram.web.dto.CMRespDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.security.Principal;

@RequiredArgsConstructor
@RestController
public class SubscribeApiController {


    private final SubscribeService subscribeService;

    @PostMapping("/api/subscribe/{toUserId}")
    public ResponseEntity<?> subscribe(@AuthenticationPrincipal PrincipalDetails principalDetails, @PathVariable int toUserId) {
        subscribeService.구독하기(principalDetails.getUser().getId(), toUserId);
        return new ResponseEntity<>(new CMRespDto<>(1, "구독하기 성공", null), HttpStatus.OK);
    }

    @DeleteMapping("/api/subscribe/{toUserId}")
    public ResponseEntity<?> unSubscribe(@AuthenticationPrincipal PrincipalDetails principalDetails, @PathVariable int toUserId) {
        subscribeService.구독취소하기(principalDetails.getUser().getId(), toUserId);
        return new ResponseEntity<>(new CMRespDto<>(1, "구독취소하기 성공", null), HttpStatus.OK);
    }
}

 

구독하기가 요청되면

@Pathvariable 에 toUserId(구독당할아이디)를 집어넣고 principalDetails 에서 세션정보를 불러와서

서비스에 같이 넘긴다.

 이 과정에서 ResponseEntity 객체를 리턴한다 (body값과 Http상태값을 받음)

 


@RequiredArgsConstructor
@Service
public class SubscribeService {

    private final SubscribeRepository subscribeRepository;

    @Transactional
    public void 구독하기(int fromUserId, int toUserId){

        try{
            subscribeRepository.mSubscribe(fromUserId, toUserId);
        }catch(Exception e){
            throw new CustomApiException("이미 구독 되었습니다.");
        }



    }

    @Transactional
    public void 구독취소하기(int fromUserId, int toUserId){
     subscribeRepository.mUnSubscribe(fromUserId,toUserId);

    }
}

 

컨트롤러에서 구독하기(principalDetails.getUser().getId(), @Pathvariable toUserId) 를 보냈기 떄문에(둘다 int값)

 서비스단에서 구독하기(int fromUserId, int toUserId)로 받았고

Repository에 따로 쿼리 선언한거 수행하면 된다.

 

또한 이 과정에서 try-catch 로 묶어서 CustomApiException 객체로 리턴

 

 

package com.pyo.pyostagram.handler.ex;

import java.util.Map;


//얘는 validation과 상관없음
public class CustomApiException extends RuntimeException {


    //객체를 구분할때
    private static final long serialVersionUID = 1L;


    public CustomApiException(String message) {
        super(message);
    }


}

 

어차피 유효성 체크도 아니기 때문에 단순하게 메세지를 리턴하는 방식으로 하기위해 새로 만들었다.

 

 


@RestController
@ControllerAdvice
public class ControllerExceptionHandler {

    @ExceptionHandler(CustomValidationException.class)
    public String validationException(CustomValidationException e){
        //CMRespDto, Script 비교
        // 1. 클라이언트한테 대답하면 Script가 좋음
        // 2. Ajax통신 - CMRespDto가 좋음
        // 3. android 통신 - CMRRespDto
        return Script.back(e.getErrorMap().toString());

    }

    @ExceptionHandler(CustomValidationApiException.class)
    public ResponseEntity<?> validationApiException(CustomValidationApiException e){

        return new ResponseEntity<>(new CMRespDto<>(-1,e.getMessage(), e.getErrorMap()),HttpStatus.BAD_REQUEST);

    }
    @ExceptionHandler(CustomApiException.class)
    public ResponseEntity<?> apiException(CustomApiException e){

        return new ResponseEntity<>(new CMRespDto<>(-1,e.getMessage(),null),HttpStatus.BAD_REQUEST);

    }

}

 

 

 

ExceptionHandler 에도 추가하자.

댓글