계층 구분 & 어느 계층부터 구현

박영준·2023년 6월 25일
0

Spring

목록 보기
19/58

1.계층 구분

Spring 프로젝트를 구성할 때 이런 방식으로 계층을 나눴다.

Controller

// 게시글 작성
@PostMapping("/board")
public BoardResponseDto createBoard(@RequestBody BoardRequestDto requestDto) {
    return boardService.createBoard(requestDto);
}
  • Client의 요청을 받았을 때, Service(해당 요청에 대해 실제 업무 수행)를 호출

    • 이때, (Client 보낸 데이터 있을 경우) 전달하기 쉽게 데이터를 가공
  • 업무 수행이 완료되면, 그 결과를 바탕으로 화면을 구성하도록 View 에 전달

  • Dto 에 데이터를 담아 Client에게 반환

Service

// 게시글 작성
public BoardResponseDto createBoard(BoardRequestDto requestDto) {
    Board board = new Board(requestDto);        // RequestDto -> Entity
    Board saveBoard = boardRepository.save(board);      // DB 저장
    BoardResponseDto boardResponseDto = new BoardResponseDto(saveBoard);        // Entity -> ResponseDto

    return boardResponseDto;
}
  • 데이터 가공

    • Controller의 요청(Client에게서 넘어온 요청)을 받아, 해당 요청에 알맞은 정보로 가공 후 DB 로 전달
    • DB 에서 받아온 데이터를 전달 받아 가공 후, Client 에게 재전달
  • DB 정보가 필요할 때는 Repository에게 요청

  • Repository를 상속받아 .findByID , .save()등의 함수 사용이 가능해진다.

    private final BoardRepository boardRepository;
    
    public BoardService(BoardRepository boardRepository) {
        this.boardRepository = boardRepository;
    }

Dto

  • 데이터를 저장해서, 계층간에 데이터를 교환해주는 객체

  • request 와 response 는 Client(사용자) 기준으로 생각하면 쉽다.

    • 사용자가 해당 정보를 요청했다. request -->
    • 사용자가 요청한 정로를 응답받았다. <-- response
  • 로직을 갖고 있지 않다.

  • 순수한 데이터 객체이며, getter, setter 메소드만을 갖고 있다.

  • Dto의 필요성

    • Entity가 아닌 DTO를 전달함으로써 각 레이어 간 역할을 분리할 수 있다.
    • 데이터를 전송하기 위한 직렬화 메커니즘을 캡슐화를 돕는다.
      • 직렬화를 캡슐화함할 경우, 이 로직에서 DTO는 제외하고 직렬화를 변경할 때 DTO 가 명확한 지점을 제공해준다.

requestDto

@Getter
public class BoardRequestDto {
        private String title;           // 제목
        private String username;        // 작성자명
        private String password;        // 비밀번호
        private String contents;        // 작성 내용
}

responseDto

@Getter
public class BoardResponseDto {
    private Long id;        // 게시글 구분을 위한 id 값
    private String title;       // 제목
    private String username;    // 작성자명
    private String contents;    // 작성 내용
    private LocalDateTime createdAt;        // 게시글 생성 날짜
    private LocalDateTime modifiedAt;       // 게시글 수정 날짜

    private String msg;     // 게시글 삭제 시, 삭제 성공 메시지


    public BoardResponseDto(Board board) {
        this.id = board.getId();
        this.title = board.getTitle();
        this.username = board.getUsername();
        this.contents = board.getContents();
        this.createdAt = board.getCreatedAt();
        this.modifiedAt = board.getModifiedAt();
    }

    // 게시글 삭제 시, 삭제 성공 메시지
    public BoardResponseDto(String msg) {
        this.msg = msg;
    }
}

Repository

public interface BoardRepository extends JpaRepository<Board, Long>  {
    List<Board> findAllByOrderByModifiedAtDesc();		// Service 계층에서 '게시글 전체 조회'를 위해 사용되는 메서드
}
  • DB 관리 (연결, 해제, 자원 관리)

    • Entity에 의해 생성된 DB에 접근하는 메서드를 사용하기 위한 interface
    • DB에 CRUD의 명령을 실행하게 만드는 인터페이스
  • JPA를 상속받음으로써, 기본적인 CRUD의 동작(함수 사용)이 가능해진다. (그래서 이렇게 간단히 표현 가능해짐)

    • JpaRepository<대상 엔티티, Entity에 접근할 객체의 Type>
  • '저장소'라는 뜻을 가진 단어

  • JPA에서 Repository 인터페이스를 생성 후,
    JpaRepository<Entity, 기본키 타입>을 상속받으면(extends하면)
    기본적인 Create, Read, Update, Delete가 자동으로 생성됨

Entity

@Entity
@Getter
@Setter
@Table(name = "board")
@NoArgsConstructor
public class Board extends Timestamped {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "title", nullable = false)
    private String title;

    @Column(name = "username", nullable = false)
    private String username;

    @Column(name = "password", nullable = false)
    private String password;

    @Column(name = "contents", nullable = false, length = 500)
    private String contents;

    // 게시글 작성
    public Board(BoardRequestDto requestDto) {
        this.title = requestDto.getTitle();
        this.username = requestDto.getUsername();
        this.password = requestDto.getPassword();
        this.contents = requestDto.getContents();
    }
  • Db의 테이블과 매핑되며, Entity class라고도 부른다.

    • 실제 DB에 저장되는 내용들을 구현하는 class
  • 하나의 객체가 DB의 하나의 Column처럼 작용

2.어느 계층부터 구현

프로젝트를 만들어보는 중 어느 계층부터 구현하기 시작해야할지에 대해 의문이 들었다.
그리고 기술 매니저님께 여쭤본 답변에 기반해서 작성헀다.

큰 흐름을 보면, DB를 중심으로 구현하는 것이 올바른 방법이라 할 수 있다.

1순위

Entity

  • DB 로 간주되는 entity이므로 가장 먼저 구현이 필요하다.

2순위

Repository

  • DB를 관리하는 계층이므로, Entity 다음으로 구현이 필요하다.

3순위

resquestDto

  • Client 자신이 필요한 정보가 어떤 것인지
    • 즉, 가공될/주고받아질 데이터는 어떤 것인지 정하는 것이 필요하다.

4순위

자유

  • 이때부터는 개발자 각자의 취향에 따라 나뉜다.
    • Controller
    • Service
    • responseDto
    • ...

참고: Spring Controller , Service , Repository , Domain , DTO
참고: dTo / Controller, Service, Repository 란?

profile
개발자로 거듭나기!

0개의 댓글