[SpringMVC]서비스 계층

이용준·2023년 1월 5일
0

Spring

목록 보기
5/6

Service 계층

  • 데이터베이스 영역과 도메인 영역을 연결해주는 매개체
  • 사용자의 요청(request)에 대한 처리를 결정
  • Controller가 받은 요청에 대한 정보를 가공해 다시 Controller에게 데이터 전달

서비스 클래스 구현

  • Page 클래스 구현(Entity)

    @Setter
    @Getter
    @AllArgsContructor
    @NoArgsContructor
    public class Page {
       private Long id;
       private String title;
       private String writer;
    }
  • PageService 클래스 구현

    public class PageService {
       public Page createPage(Page page){
           Page createPage = page;
           return createPage;
       }
       public Page updatePage(Page page){
           Page updatePage=page;
           return updatePage;
       }
       public Page findPage(Page page){
           Page findPage = page;
           return findPage;
       }
       public Page deletePage(Page page){
           Page deletePage=page;
           return deletePage;
       }
    } 
  • PageController 클래스 구현(Service 적용 전)

    • API 계층과 Service 계층 연동 전

      @RestController
      @RequestMapping("/pages")
      @Validated
      public class PageController {
         @PostMapping
         public ResponseEntity postPage(@Valid @RequestBody PagePostDto PageDto) {
             return new ResponseEntity<>(PageDto, HttpStatus.CREATED);
         }
         @PatchMapping("/{page-id}")
         public ResponseEntity patchPage(@PathVariable("page-id") long pageId,
                                         @Valid @RequestBody PagePatchDto PagePatchDto){
             pagePatchDto.setPageId(pageId);
             
             return new ResponseEntity<>(PagePatchDto, HttpStatus.OK);
         }
         ...
      }
         
         --------------------------------------
         - postPage() : 글 등록을 위한 요청을 받는다.
         - patchPage() : 글 수정을 위한 요청을 받는다.
         - 이 외에도 찾기, 삭제 등의 기능을 추가할 수 있다.
      
    • DI를 적용한 계층간 연동

      public class PageController {
       private final PageService pageService;
        public PageController(PageService pageService){
          this.pageService = pageService;
        }
       --------------------------------------
        [문제점]
        1. PageController 핸들러 메서드가 DTO 클래스를 엔티티 클래스로 변환하는 작업까지 진행한다.
        2. 엔티티 클래스의 객체를 클라이언트 응답으로 전송하므로 계층 간 역할 분리되지 않음
        
        >> DTO 클래스와 엔티티 클래스를 서로 변환하는 mapper 활용

MapStruct를 이용한 Mapper 자동 생성

MapStruct는 매퍼 구현 클래스를 자동으로 생성해주는 코드 자동생성기

  • buil.grale(의존 라이브러리 설정)

    dependencies {
    	...
    	implementation 'org.mapstruct:mapstruct:1.4.2.Final'
    	annotationProcessor 'org.mapstruct:mapstruct- processor:1.4.2.Final'
    }
    
  • MapStruct 기반의 매퍼 인터페이스 정의

    • 자동 생성된 PageMapper의 구현 클래스는 build task 통해 확인 가능
      import com.example.page.dto.PagePatchDto;
      import com.example.page.dto.PagePostDto;
      import com.example.page.dto.PageResponseDto;
      import com.example.page.entity.Page;
      import org.mapstruct.Mapper;
      @Mapper(componentModel = "spring")  /Bean 등록
      public interface PageMapper {
        Page pagePostDtoToPage(PagePostDto pagePostDto);
        Page pagePatchDtoToPage(PagePatchDto pagePatchDto);
        PageResponseDto pageToPageResponseDto(Page page);
      }
  • PageController 핸들러 메서드에 MapStruct 적용

    • MapStruct 인터페이스 경로 import
      import com.example.page.mapstruct.mapper.PageMapper  // 경로 적용 
      @RestController
      @RequestMapping("/pages")
      @Validated
      public class PageController {
      private final PageService pageService;
        public PageController(PageService pageService){
          this.pageService = pageService;
        }
        

DTO 클래스와 엔티티 역할 분리 필요한 이유

  1. 계층별 관심사의 분리
    • 계층별 역할 상이
    • 하나의 클래스나 메서드 내에서 여러 개의 기능들을 구현하고 있는 것은 객체 지향 코드 관점에서도 리팩토링 대상
  2. 코드 구성 단순화
  3. REST API 독립성 확보
  • 회원 정보를 클라이언트에 노출하지 않고, 원하는 정보만 제공 가능
profile
뚝딱뚝딱

0개의 댓글