TIL-Scheduler API 설계/ERD_25.03.25

kb·2025년 3월 25일

Spring

목록 보기
8/21

Scheduler 요구사항 및 필요 요소 정리

  1. Entity
1. 일정 : 할 일/ 작성자명 / 비밀번호 / 작성일 / 수정일
2. 작성자 : 이름(작성자명) / 이메일 / 등록일(작성일) / 수정일
3. 페이지: 일정 번호 / 페이지 번호

2&3. Controller / Service

1. 일정 생성 / POST
2. 전체 일정 조회 / GET
3. 선택 일정 조회 / GET
4. 선택 일정 수정 / PUT(PATCH)
5. 선택 일정 삭제 / DELETE
  1. Repository
1. 작성자: {{작성자 1}, {작성자2}, ...}
2. 일정: {{일정1}, {일정2}, ...}
3. 페이지: 
  1. Dto
RequestDto: 할 일/ 작성자명 / 비밀번호 / 작성일 / 수정일
ResponseDto: 할 일/ 작성자명 / 작성일 / 수정일

요소 세부 설계

설계 과정에서 어려운점

  • Controller : input과 output은 어떤 형태여야 하는지?

    • input은 @PathVariable Long id와 @RequestBody ScheduleRequestDto scheduleRequestDto인 것 같다. 이유는, URL에서 정해준 값(/{id})으로 어떤 데이터를 호출할지를 결정하고, ScheduleRequestDto가 사용자의 입력값(Body)를 받아와야 하기 때문이다.
    • output은 메서드마다, Service.메서드()의 리턴값이 되어야할 것이다. 이 리턴 값은 ResponseEntity<>(ScheduleResponseDto)형태일 것이다.
    • 그렇다면, Controller의 메서드는 ResponseEntity< ScheduleResponseDto > findScheduleById(@PathVariable Long id, @RequestBody ScheduleRequestDto scheduleRequestDto) { return ResponseEntity< ScheduleResponseDto > }와 같은 형태여야 하지 않을까?
    • 여기서 질문, @RequestBody 이전에 RequestEntity가 필요한 것 아닐까? RequestEntity로 입력받은 값을 Schedule 클래스로 만들어주고, 이걸 RequestDto로 넣어주거나, RequestEntity로 입력받은 값을 RequestDto로 바꿔주고, 이걸 Schedule 클래스로 만들어 Repository에 저장하거나.
    • 이 내용에 대해 맞게 이해했는지 GPT에게 검토를 요청함. RequestEntity는 어떻게보면 RequestBody와 중복되는 내용이라고 함. 아! 그러면 RequestBody로 입력값을 받아서, Repository에서 번호를 생성해 저장하고 리스트에 담아주면 되겠네!
    • 오! 생각보다 잘 이해했다고 해서 좀 놀랐다. 메서드의 출력 양식을 ResponseEntity< ScheduleResponseDto > 이렇게 정의하는게 맞는지도 의심스러웠는데, 맞다고 한다! 감격!
    • Controller는 RequestDto를 받아 Service로 넘겨주고, Service에서는 이 RequestDto를 Entity로 변환해 DB와 주고받고 ResponseDto로 변환해서 Controller에 넘겨주면 된다! 오! 조금 구조 파악이 됨!
  • Service : input과 output은 어떤 형태여야 하는지

    • 위의 설계가 맞다면, Service에서는 Controller에서 호출하는 메서드를 설계해야한다. 예를들어, Controller에서 createSchedule메서드 내에서 Service.createSchedule(scheduleRequestDto)를 호출한다면, Service에서는 createSchedule(ScheduleRequestDto scheduleRequestDto)를 받아 정의해줘야 함. 메서드의 반환 형식은 ScheduleResponseDto가 되어야 함. 그래야 Controller에서 이 값을 ResponseEntity< ScheduleResponseDto >로 받아 return해줄 수 있게 됨
    • 질문. Controller에서의 반환값을 ResponseEntity < ScheduleResponseDto > (scheduleResponseDto(Service에서 반환한 값), HttpStatus.OK) 이렇게 하면 Service 메서드가 반환한 scheduleResponseDto와 HttpStatus가 함께 반환되는 것이 맞나?
    • 아니네! return new ResponseEntity<>(scheduleResponseDto, HttpStatus.OK)와 같이 리턴해줘야하네. Controller가 반환할 때는 ResponseEntity를 새롭게 생성하고(new ResponseEntity<>) 생성된 값이 Service가 반환한 responseDto(scheduleResponseDto)와 처리상태(HttpStatus.OK)를 담아 반환해준다!
  • Repository : RequestBody로 받은 ScheduleRequestDto를 Entity로 변환하거나, PathVariable로 받은 값을 조회해 Entity로 내어주는 역할

    • ScheduleRequestDto -> Entity -> DB 조회/생성 -> Entity 반환
    • 그렇다면, Repository에 저장하기 위한 메서드가 필요하다. Schedule schedule saveSchedule(ScheduleRequestBody scheduleRequestBody)와 같이, requestBody를 받아 Entity로 변환해주고(RequestBody에 없던 값 생성), DB List에 추가해줘야한다.
    • 그렇다면, Repository에는 List< Schedule > scheduleList = new ArrayList<>();가 정의되어 있거나, 생성되어야 한다. 어떻게 생성할까? 변환할 수 없도록 final이 되어야 할 것 같다.
    • final이 되어야한다고 생각하는 이유는, scheduleList자체는 변할 수 없고, 안에 있는 요소만 추가하거나 삭제하거나 하는 등 변경할 수 있도록 하기 위함이다. 근데 JDBC를 사용하면 final 이런게 필요가 없을 수도 있다는 생각도 든다. 어제 JDBC 관련해 정리한 내용을 복습해보자.
    • ScheduleRepository 클래스에서 (DataSource dataSource)를 입력 변수로 받아서, {this.JdbcTemplate = new JdbcTemplate(dataSource)}로 생성해주는 것 같다. dataSource가 뭔지 파헤쳐볼 필요가 있다.
    • 보니까, ScheduleRepository 생성자 이전에, private final JdbcTemplate jdbcTemplate을 속성으로 갖네! 이 ScheduleRepository 클래스는 jdbcTemplate을 속성으로 갖는다.
    • 아! 그리고 Repository 클래스는 @Repository Annotation을 넣어줘야 한다. 이유는?
    • Repository Class에서 List< Schedule > findById(Long id) 메서드로 Schedule 객체를 Return 해주는 함수가 필요하다! jdbc문법을 쓰는데, 이건 jdbc문법을 보고 따라써야할 것 같다. 이 과정을 거치면 Entity인 Schedule schedule = new Schedule; 인스턴스를 설정하고, 이 인스턴스 schedule에 속성들(id, 작성자, 할일, 작성일, 수정일, 비밀번호)을 설정해준다.
    • Schedule뿐만 아니라, 유저 정보도 입력으로 받아 Repository에 저장해줘야 한다. users는 또 새로운 테이블이 필요한데, 이건 SQL을 이용해서 생성해줘야하는게 아닌가 싶다. SQL 문법으로 프로젝트 안에서 생성해야할 듯. Java는 이 테이블과 Java 프로그램을 연결시켜주는 역할만. 테이블 생성까지 Java에게 맡기는 건 아닌 것 같다.
    • user 테이블이 생겼다면, jdbcTemplate에서 쿼리로 from user / from scheduleList s join user u on s.writer = u.name 이런식으로 쿼리를 짜서 데이터를 갖고올 수도 있을 것 같다. 여기까지 GPT한테 검사 받아보자!
    • 거의 맞게 이해했다고 함! 다행이다! 다만, RequestDto -> Entity는 보통 서비스단에서 해서 Repository에는 Entity를 넘겨준다고 함. 이 과정이 잘 이해되지 않아 G선생님께 물어봄
    • Service단 메서드에서 RequestDto를 받아 Entity 속성을 부여해주고 DB에 저장하는 메서드를 실행한 후, return으로 ResponseDto 출력해 Controller로 넘겨주는 흐름!
  • Entity : entity의 속성을 모두 가져야하는지. 생성자나 메서드가 필요한지.

    • Entity 클래스명이 Schedule이었다면, 생성자는 Schedule(RequestDto requstDto) {this.속성1 = requestDto.get속성1() ... } 이런식으로 해줘야하나? 그런 것 같은 느낌. Entity가 생성되려면 RequestDto가 무조건 있어야하니까, 이걸 받아서 속성으로 할당해주는 것이 논리적으로 맞는 흐름임
    • Entity는 @Getter와 @Setter를 가져야할 듯. 게터는 Repository에서 값을 할당할 때, Setter는 RequestDto에서 Entity 속성으로 값을 할당해줄 때 필요할 것 같다.
    • 메서드는 Update가 필요할 것 같다. 기존에 저장되어 있던 데이터의 일정 값만 바꿔주려면, Entity에서 바꿀 속성값들을 업데이트 한 다음 Repository로 넘겨주는 것이 맞는 흐름인 것 같음. 이외 조회/삭제는 Repository에 있는 데이터를 대상으로 Repository 안의 요소를 바꾸는 로직이므로 Repository 클래스에서 해주면 될 것 같다.
    • DB에 저장되는 포맷! 실제 저장되는 데이터의 양식을 정의해준다.
    • Controller가 RequestDto를 받아 Service 단의 메서드로 넘겨주면, Service 단에서 Entity로 변경한 다음 DB에 저장하거나 조회, 수정, 삭제 등의 요청을 Repository에 실행시키고, 이 Entity를 다시 ResponseDto로 변경해 반환해줌. Controller는 이 ResponseDto를 받아 Return해줌.
    • 여기까지 Dr.G에게 물어보자.
    • 오! 여기까지도 전반적으로 잘 이해했다고 한다! 다만, Entity의 경우 @Setter는 설정하지 않고, this.속성1 = RequestDto.get속성1() 이런식으로 설정하는 경우가 많아 Setter 설정은 하지 않는다고 한다. immutable 뭐라고 했던 것 같은데 ... 불변성(immutable)을 지키고, 값 변경을 통제하기 위함이라고 하고, 값을 바꿔야할 경우엔 보통 업데이트용 메서드를 만들어 사용한다고 한다! 으음~ 이정도면 Entity 개념과 연결되는 파트들도 어느정도 감이 잡힌 것 같다.
  • Dto : (RequestDto / ResponseDto)에 생성자를 정의해줘야 하는지

    • 속성은 갖고, RequestDto는 생성자를 갖지 않는데(RequestBody로 받아주니까?) ResponseDto는 Entity를 받아서 생성되니까 Entity를 생성자에서 입력으로 받아줘야할 것 같다. Controller에서 @RequestBody ScheduleRequestDto scheduleRequestDto로 입력을 받아주는데, @RequestBody가 ScheduleRequestDto의 양식에 맞춰 속성을 정의해주는 건가? 싶다. 이렇게 입력값의 클래스를 ScheduleRequestDto / 인스턴스를 scheduleRequestDto로 설정해준다면, RequestDto의 생성자에서 받는 입력값은 없는게 맞는 것 같은데, Dr.G의 확인이 필요하다.
    • RequestDto는 속성을 갖고, 생성자는 X, 기능(메서드)은 X
    • ResponseDto는 속성을 갖고, 생성자는 Entity, 기능(메서드)는 X와 같이 정의할 것 같다!
    • Dr.G의 피드백을 받아보자.
    • 오! 전반적으로 DTO의 역할, 생성자 유무, 메서드 포함 여부까지 이해가 매우 정확하다고 한다! DR.G는 조련을 참 잘하는 선생님인 것 같다. 그럼, 이 설계를 바탕으로 ERD를 설계해보자.

ERD 설계

  • ERD ... API 설계가 서비스의 큰 흐름과 기능을 파악하기 위한 용도라면, 기능 구현을 위해 필요한 데이터가 무엇인지 설계가 필요하다.
    • 구현해야할 서비스 영역별로 필요한 데이터를 설계하고, 영역간의 관계를 표현하는 방법(Entity Relationship Diagram)
    • E (Entity: 개체) ... 구현할 서비스 영역에 필요한 데이터를 담을 개체
    • A (Attribute) ... 각 개체가 가지는 속성
    • R (Relationship) ... 개체들 사이의 관계
    • E가 A를 포함하고 R은 E를 연결한 것이겠다. 그래서 그림으로 표현하는구나.
    • 플랫폼 사용이 어렵다. Page의 속성도 어떻게 설정해주어야할지 좀 감이 안 잡힌다. 우선 Page를 제외하고 구현한 다음, Page를 고민해보는 방향으로 진행해봐야겠다.
    • 유저 1명이 0~N개의 schedule을 생성할 수 있으므로 이에 맞는 관계를 화살표로 표시해줬다.
    • 페이지도 마찬가지로, 0~N개의 schedule이 하나의 Page에 할당될 수 있으므로 이에 맞는 관계를 화살표로 표시해줬다.
    • 이에 맞춰 SQL로 DB를 생성하고, API 설계에 따라 프로젝트를 구현해보자!
profile
Experience

0개의 댓글