➡️ 서비스 계층과 API 계층이 연동한다는 의미는 API 계층에서 구현한 Controller 클래스가 서비스 계층의 Service클래스와 메서드 호출을 통해 상호작용한다는 것을 의미함
🔎 Service?
➡️ 애플리케이션에 있어 Service의 의미는 도메인 업무 영역을 구현하는 비즈니스 로직과 관련 있음
➡️서비스 계층은 비즈니스 로직을 처리하기 위해 대부분 도메인 모델을 가지고 있고 그 모델은 빈약한 도메인 모델(anemic domain model)과 풍부한 도메인 모델(rich domain model)로 구분할 수 있음 또한 DDD(도메인 주도 설계, Domain Driven Design)과 관련이 깊음
🔎 연동 실습
MemberService
Controller와 DTO 실습 내용을 바탕으로 Service 클래스 작성
MemberController의 핸들러 메서드와 1 : 1로 매치가 되는 것을 알 수 있음
메서드 파라미터와 리턴값으로 Member 타입 사용
Member 클래스의 역할? : DTO가 API 계층에서 클라이언트의 RequestBody를 전달받고 클라이언트에게 되돌려 줄 응답 데이터를 담는 역할을 한다면 Member 클래스는 API 계층에서 전달받은 요청 데이터를 기반으로 서비스 계층에서 비즈니스 로직을 처리하기 위해 데이터를 전달받고 비즈니스 로직을 처리한 후에 결과 값을 다시 API 계층으로 리턴해주는 역할을 함 → Member 클래스와 같이 서비스 계층에서 데이터 액세스 계층과 연동하면서 비즈니스 로직을 처리하기 위해 필요한 데이터를 담는 역할을 하는 클래스를 도메인 엔티티(Entity) 클래스라고 부름
Member 클래스
Member 클래스 안에 API 계층에서 사용했던 DTO 클래스에서 사용한 멤버 변수들이 모두 포함되어 있음
@Getter, @Setter : lombok 라이브러리에서 제공하는 애너테이션, 각 멤버 변수에 해당하는 getter/setter 메서드를 일일이 작성하는 수고를 덜어주는 편리한 유틸리티성 라이브러리
@AllArgsConstructor : 현재 클래스에 추가된 모든 멤버 변수를 파라미터로 갖는 생성자 자동으로 생성해줌
@NoArgsConstructor : 파라미터가 없는 기본 생성자 자동으로 생성
Service 클래스 수정
Stub 데이터? : 테스트나 개발 과정에서 실제 데이터를 대체하여 사용하는 가짜 데이터
Controller 일부
Controller 클래스에 @RestController 애너테이션을 추가하면 Spring Bean으로 등록됨
Service 클래스에 @Service 애너테이션을 추가하면 Spring Bean으로 등록됨
생성자 방식의 DI는 생성자가 하나일 경우에는 @Autowired 애너테이션을 추가하지 않아도 DI가 적용됨
왼쪽 상단 Gradle 클릭하고 [프로젝트명 - Tasks - build - build 더블 클릭] 이렇게 하면 구현 클래스가 생성됨
build 디렉토리에서 생성된 구현 클래스 확인 가능함!
✔️ DTO 클래스와 엔티티 클래스를 매핑해서 변환하는 이유 (역할 분리의 이유)
계층별 관심사의 분리 ➡️ 서로 사용되는 계층이 다름, 즉 기능에 대한 관심사가 다름 그렇게 때문에 분리를 하는 것 ➡️ 하나의 클래스나 메서드에서 여러 개의 기능을 구현하는 것은 객체 지향적이지 못함
코드 구성의 단순화 ➡️ 만약 DTO 클래스에서 사용하는 유효성 검사 애너테이션이 Entity 클래스에서 사용된다면 JPA에서 사용하는 애너테이션과 뒤섞인 상태가 되어 유지보수하기가 상당히 어려운 코드가 됨
3. REST API 스펙의 독립성 확보 ➡️ 데이터 액세스 계층에서 전달받은 데이터로 채워진 Entity 클래스를 클라이언트의 응답으로 전달하게 되면 원치 않는 데이터까지 클라이언트에게 전송될 수 있음 ➡️ 위의 경우 DTO 클래스를 사용하면 회원의 로그인 패스워드 같은 정보를 클라이언트에게 노출하지 않고 원하는 정보만 제공할 수 있음