개발 일기

UserApiController -> 서비스 분리 본문

Java&Spring/Project

UserApiController -> 서비스 분리

flow123 2021. 12. 15. 23:58

리팩토링을 하면서, Controller 와 서비스를 분리하는 것이 중요 과제였다. 

Controller

1) 클라이언트의 요청 받음 

2) 요청에 대한 처리는 서비스에게 전담 

3) 클라이언트에게 응답. 

Service

사용자의 요구사항 처리 

DB 정보가 필요하면 Repository에 전담

Repository

-DB 관리 

-DB CRUD 처리 

왜 Controller/Service 구분하지? 

-중복되는 코드가 생기기 때문. 

-비즈니스 로직 코드가 컨트롤러에 구현되어 있는 경우 다른 컨트롤러의 핸들러 메소드에서 똑같은 로직 코드를 구현해야함. -> 중복 코드 발생/재사용정이 줄어듬. 

 

*아래 블로그에서 명료하게 정리해주셔서 참고하였다. 

출처 https://velog.io/@sezeom/Controller-Service-Repository-%EB%B6%84%EB%A6%AC-%EC%9D%B4%EC%9C%A0

 

참고로 new UsernamePasswordAuthenticationToken 는 authentication 내장 클래스다. 

내장 문서를 보면, principal 과 credentials 라는 파라미터를 받는다.

Spring Security에서는 Credential 기반의 인증방식을 쓰는데, Principal을 아이디로, Credential을 비밀번호로 사용한다. 

Principal 은 리소스에 접근하는 대상, Credentials 는 그 대상의 비밀번호를 뜻한다.

 

스프링 UsernamePasswordAuthenticationToken 설명서 (intelliJ 에서 Ctrl+ 클릭)

public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
   super(null);
   this.principal = principal;
   this.credentials = credentials;
   setAuthenticated(false);
}

스프링 AuthenticationManager 설명서

public interface AuthenticationManager {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
}

authenticate 은 authenticationManager 에 내장된 메서드다.

위의 코드에서 보듯, 원래의 내장 authenticate 은 authentication 객체 하나만 들어간다. 

그러니 아래와 같이 .authenticate(new UsernamePasswordAuthenticationToken(username, password));

authenticate 을 재정의 해줘야 한다. 

 

 

기존 방식에서 Authenticate 코드는 Controller 에 있었다. 

-> 프론트와 매핑하는 코드가 아니기 때문에, 굳이 Controller 에 있을 필요가 없다. 그냥 Service 로 옮겨버린다. 

    private void authenticate(String username, String password) throws Exception {
    try {
        authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
    } catch (DisabledException e) {
        throw new Exception("USER_DISABLED", e);
    } catch (BadCredentialsException e) {
        throw new Exception("INVALID_CREDENTIALS", e);
    }
}

*원래는, toAuthenticate 이라는 또다른 메서드를 아래와 같이 컨트롤러에 만들어서 Controller 와 Service를 분리하려 했다. 애초에 프론트와 소통해서 꼭 Controller 가 Mapping 을 해줘야 하는 코드가 아니다. 

그러니 이런 코드는 필요 없는 것. 

    private void authenticate(String username, String password) throws Exception {
        UserService.toAuthenticate(username, password);

    }

 


 

 

ResponseEntity란? 

 

HTTP 를 상속받아 구현한다. 

HTTP Request 에 대한 응답 데이터: HTTPStatus, HTTPHeaders 등을 포함함. 

public class ResponseEntity<T> extends HttpEntity<T> 

 

참고

https://mangkyu.tistory.com/76

Comments