(25. 10. 16)
3 Layer Architecture
: 소프트웨어 시스템을 3개의 논리적 계층으로 분리하는 아키텍처. 각 Layer의 역할(책임)을 분리해 유지보수성+확장성+재사용성을 향상할 수 있다.
Controller Layer
: 사용자 - 애플리케이션 간 상호작용을 담당하는 커뮤니케이션 계층
- HTTP 요청(POST, GET, PUT, DELETE 등) 매핑
- 요청 파라미터 검증(@PathVariable)
- 응답 데이터 변환
- 예외 처리 및 에러 응답
Service
: 비즈니스 로직 처리를 담당하는 계층
- 핵심 로직 운영(각종 데이터source 조합)
- 데이터 유효성 검증
- 트랜잭션 경계 설정
Repository
: DB와 상호작용을 담당하는 계층. 실제로 DB에서 데이터를 저장하거나 가져온다.
- CRUD 연산 구현
- 쿼리 최적화
- 데이터 매핑
⇒ 딴 생각하지 말고 nullable은 모두 false로 구현하자...!
전체 조회
단 건 조회
⇒ ID를 통해 삭제할 일정을 선택하도록 한다.

필수 기능 구현까지는 일정 Entity 단일로 구성되어 있다. 그래서 Relationship은 도전 기능까지 구현할 수 있다면…추가해보도록 하겠다.
(25. 10. 17)
대부분 실습에서 진행했던 순서대로 진행했다.
1. DB & JPA DDL 설정
MySQL로 데이터베이스를 추가하고 DDL 설정을 application.properties에 작성해줬다.
이 과정에서 직접 파일에 한줄한줄 적어봤는데(공부 의도X...강의자료를 다른 컴에 열고 있어서 또 노트북에서 열기 귀찮았음)
❗ 오타가 나서 앱 실행 ERROR가 발생했다.
spring.datasource.url=jdbc:mysql://localhost:3306/Schedule
// Schedule = DB명
spring.datasource.username=root
// root = DB 만들 때 입력한 사용자명
spring.datasource.password=********
// 마찬가지로 DB 만들 때 입력한 비밀번호
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
// 여기서 'MYSQL'로 오타내서 오류가 났다...ㅠ
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
그래도 문제의 부분을 금방(나의 금방은 매우 길다...)해결했다
3 Layer Architecture 작성

CRUD 작성
상세 코드는 GitHub 참조
Postman 테스트
POST - 성공
GET - 성공
PUT - 성공
DELETE - 성공
POST -
GET -
PUT -
DELETE -
Get Response 처리 DTO에 id 값을 넣지 않았다. 그러니까 당연히 안 보이시겠죠...?
GetScheduleResponse에 id 값을 포함해서 응답 처리하도록 작성했다.
@Getter public class GetScheduleResponse { // 하단의 id 값을 적는 걸 까먹었다.. private final Long id; private final String title; private final String content; private final String registrant; private final LocalDateTime createdAt; private final LocalDateTime modifiedAt; public GetScheduleResponse(Long id, String title, String content, String registrant, LocalDateTime createdAt, LocalDateTime modifiedAt) { // 위에 매개변수로는 언급해놓고 아랫줄도 까먹고 안 적었다.. this.id = id; this.title = title; this.content = content; this.registrant = registrant; this.createdAt = createdAt; this.modifiedAt = modifiedAt; } }

작성자명으로 GET 조회(작성자명에 해당되는 건 전체 조회)
→@GetMapping("/schedules/{작성자명}")
id로 단 건 조회
→@GetMapping("/schedules/{id}")
id는 Long 타입이고 작성자명은 String 타입이라 구분이 될 줄 알았는데(아무생각❌) 핸들러가 둘 중에 어떤 걸로 GET 요청 처리를 해야할지 경로 매핑을 구분 못해서 오류가 발생했다.
작성자명으로 검색하는 GET 요청 경로를 @GetMapping("/schedules/register/{작성자명}")으로 수정해줬다. = 경로 구분


위에서 경로 구분을 해줬기 때문에 단 건 조회는 그대로 잘 동작한다.
다소 순서가 뒤바뀌었으나...API 작성하는 법이나 예시가 잘 감이 오지 않아서 여러 사례?를 찾아본다고 어쩔 수가 없었음
Schedule - 일정 관리 앱 API 명세서
안녕하세요? 멍청이입니다.
아무리 해도 댓글 기능을 추가해서 일정을 조회할 때 댓글Comment 내용도 같이 나오도록 시도했는데 등록(POST)조차 계속해서 실패했습니다. 아무리 찾아봐도 동작 원리는 맞는데...매핑도 잘 되었는디....?
그래서 처음부터 차근차근 다시 보면서 튜터님 코드랑 비교하고 피드백 내용도 보면서 고치고 했는데 계속 화면에 보이는 404, 500 에러코드
머리 쥐어뜯으면서 원인탐색 계속한 결과...
Controller에 POST를 구현할 때 변수로 일정의 ID와 구현해놓은 Request DTO를 넣어주는데
public ResponseEntity<CreateCommentResponse> create (@PathVariable Long scheduleId, CreateCommentRequest request)
이렇게 적어놨더라...
어느 부분이 비 었 을 까 요?
바로바로~
public ResponseEntity<CreateCommentResponse> create
(@PathVariable Long scheduleId,
**@RequestBody** CreateCommentRequest request)
원인 찾고 광명 찾았다
신나게 API 테스트 하러 달려갔고

성공했다.

이제 마음 편하게 이 과제를 놓아줄 수 있게 되었음🎉 아이신나