TIL(Today I Learned)

[TIL] 일정 관리 앱 서버 만들기 & 기능 구현

jy3574 2024. 11. 9. 23:45
프로젝트 요약

 

1. 프로젝트 목적

  • 데이터베이스와의 연동을 위해 JDBC를 사용해보며, 기본적인 SQL 쿼리 작성과 데이터 관리를 연습.
  • CRUD(Create, Read, Update, Delete) 필수 기능은 모두 데이터베이스 연결 및 JDBC를 사용해 개발.
  • 일정 관리 애플리케이션을 만들며 CRUD 필수 기능을 구현하고, 적절한 상태코드를 반환 & 적절한 오류 코드 및 메세지 반환.

 

2. 프로젝트 구현 단계

<필수 기능>

  • Lv0 : 프로젝트 설계
    • API 명세서 작성 - postman 사용
    • ERD 작성
    • SQL 작성 - MySQL 사용
  • Lv1 : 일정 생성 및 조회 기능
    • 일정 생성 - 할일, 작성자명, 비밀번호, 작성일, 수정일 데이터 포함
      • 작성일, 수정일은 날짜와 시간을 모두 포함
    • 전체 일정 조회 & 선택 일정조회
      • 수정일과 작성자명을 기준으로 조회
      • 수정일을 기준으로 내림차순 정렬
  • Lv2 : 일정 수정 및 삭제
    • 선택한 일정 수정 & 삭제
      • 서버에 비밀번호를 함께 전달
      • 수정일은 수정 완료시 수정한 시점으로 변경

<도전 기능>

  • Lv3 : 연관 관계 설정
    • 작성자와 일정의 연결 - 동명이인의 작성자가 있을 경우 구별을 위해 작성자에게 고유 식별자 부여
    • 작성자는 이름외에 이메일, 등록일, 수정일 정보를 가지고 있음
      • 작성자의 고유 식별자가 일정 테이블의 외래키가 될 수 있게 함
  • Lv4 : 페이지네이션
    • 많은 양의 데이터를 효율적으로 표시하기 위해 데이터를 여러 페이지로 나눔
    • 페이지 번호와 페이지 크기를 쿼리 파라미터로 전달
  • Lv5 : 예외처리
    • 예외 상황에 대한 처리를 위해 HTTP 상태코드와 에러 메시지를 포함한 정보를 사용하여 예외처리
      • 비밀번호가 일치하지 않을 시
      • 잘못된 정보나 삭제된 정보를 조회하려고 할 때
  • Lv6 : null 체크 및 특정 패턴에 대한 검증 수행
    • 유효성 검사 - 데이터 무결성 보장, 잘못된 입력이나 요청을 미리 방지, @Valid 어노테이션 이용

사용한 기술 및 개념

 

1. Spring Boot

-스프링 프레임 워크를 기반으로 한 애플리케이션 개발

 

2. 3-Layer Architecture

  • Controller : 사용자 요청을 받고 응답을 반환, API 요청 처리
  • Service : 비지니스 로직 처리
  • Repository : 데이터베이스와의 직접적인 상호작용, 데이터베이스와 연결하여 데이터를 저장하거나 가져옴

3. JDBC

-JDBC를 사용하여 데이터베이스를 연결

-데이터베이스의 연결 및 쿼리 수행을 쉽게할 수 있도록 도와주는 spring의 도구

 

4. DTO (Data Transfer Object)

-데이터 전송 시 필요한 객체를 요청(request)하고 응답(response) 할 수 있게 분리하여 데이터 관리

 

5. profile

-@profile 을 이용해 Lv1,2 컨트롤러를 선택적으로 활성화할 수 있게 만들고, bin을 관리

 

6. Optional, Null, RestfulAPI 사용

  • Optional : 값의 존재 여부에 따라 null에 대한 예외를 방지하기 위해 사용
  • .map(), .orElse() 를 사용하여 조건에 따른 값을 반환하게 구현함
  • RestfulAPI : HTTP 메서드를 통해 CRUD 기능을 만들고 restful 원칙에 따라 관리할 수 있게 함

직접 구현한 내용
필수 기능 구현 o
도전 기능 구현 x

 

1. Lv0 - 프로젝트 설계

1-1. API 명세서 작성 (postman 사용)

https://documenter.getpostman.com/view/39376424/2sAY4vhi4F

 

Sparta_Schedule

The Postman Documenter generates and maintains beautiful, live documentation for your collections. Never worry about maintaining API documentation again.

documenter.getpostman.com

 

1-2. ERD(Entity Relationship Diagram)

 

1-3. SQL 작성

 

 

2. Lv1 - 일정 생성 및 조회 기능

2-1. 일정 생성하기

  • 사용한 메서드 및 간단한 기능설명
    • createSchedule, ScheduleService, RequestDto, ResponseDto 생성해서 사용
    • 사용자가 입력한 데이터를 가지고 일정을 생성할 수 있게 구현
    • saveSchedule을 호출하여 데이터베이스에 저장하고, 저장 성공시 responseDto를 반환할 수 있도록 함
  • 배운점, 느낀점
    • Dto를 통해 필요한 데이터를 받아오고 생성된 스케줄 id(고유키)를 reponse로 받아와 관리하는 방식을 알게 되었다.
    • 3-Layer Architecture 구조를 직접 사용해보니 각 계층 역할에 대해서 조금 알게 되었다.
    • Dto를 사용하면서 데이터를 왜 분리해야만 하는지 알게 되었다.
    • 계층이 분리되어 있으니 코드를 추가 수정할 때 편리하다는 것을 느꼈다.

2-2. 전체 일정 조회하기, 특정 일정 조회하기

  • 사용한 메서드 및 간단한 기능 설명
    • findAllSchedules, getScheduleById, Optional, Repository 생성해서 사용
    • 전체 일정 조회를 위해 findAllSchedules 메서드를 호출
    • Optional을 이용하여 name, updateDate 를 기준으로 호출 할 수 있게 구현
    • getScheduleById 를 사용해 특정 id를 가진 일정을 가져옴
    • id가 맞지 않을 경우 404 상태코드를 반환함
  • 배운점, 느낀점
    • Optional을 이용해 선택적 조건으로 데이터를 불러올 수 있게 하는 방법을 배웠다.
    • findAllSchedule을 사용해보면서 데이터베이스 쿼리 메서드를 통해 데이터를 관리하는 방법을 알게 되었다.
    • .orElse()를 사용하여 예외처리 하는 방법을 알게 되었다.

2-3. 주요 메서드

  • Controller : @PostMapping, @GetMapping 등의 요청 어노테이션을 사용하면서 HTTP 요청을 처리하는 방법을 익힘.
  • Repository : findAllSchedules, findById 등의 쿼리 메서드를 통해 데이터베이스와의 상호작용을 배우고 데이터 관리하는 방법을 알게 됨.

 

3. Lv2 - 일정 수정 및 삭제 기능 (비밀번호 검증 포함)

3-1. 특정 일정 수정 및 삭제하기

  • 사용한 메서드 및 간단한 기능 설명
    • updateSchedule(Long id, int password) 등과 같은 형식을 사용하여 특정 조건으로 데이터에 접근할 수 있도록 함.
    • 비밀번호가 일치하는 경우에만 name과 title, contents를 수정, 삭제할 수 있도록 함
    • 비밀번호 일치할 경우 200 OK, 일치하지 않을 경우 401 Unauthorized 상태를 반환하게 함.
  • 배운점, 느낀점
    • 메서드 호출을 하여 비밀번호 검증을 하고 이를 통해 데이터베이스의 데이터를 수정하고 삭제할 수 있다는 것을 배움
    • 조건문을 사용하여 비밀번호 검증하는 방식을 알게 됨, 보안에 대해 조금 알게 되었음.

 

3-2. 주요 메서드

  • Service 계층 : updateSchedule, deleteSchedule 메서드를 통해 비지니스 로직을 처리하는 것과 비밀번호 검증하는 방법을 사용.
  • Repository 계층 : requestDto, responseDto, deleteSchedule(Long id)와 같은 것들응 사용해 수정과 삭제할 때 데이터 접근을 하는 방법을 구현함.

진행 중 어려웠던 점과 해결 방법
& 피드백

 

1. 진행 중 어려웠던 점과 해결 방법은 트러블 슈팅을 작성

https://jy3574.tistory.com/76

 

[내일배움캠프/백엔드] Spring 입문 개인과제 일정 관리 앱 만들기 트러블슈팅

- 어떤 현상을 발견했는가?1. IntelliJ 내부에서 Database 를 작성하는 중에 오류 발생2. 설정오류2-1. interface expected here2-2. cannot find symbol method2-3. method does not override or implement 3. ERROR 49429 4. properties 오

jy3574.tistory.com

 

2. 피드백

-비밀번호 전송 시 RequestParam 대신 RequestBody 사용

  • 비밀번호를 RequestParam으로 받을 경우 URL에 노출되어 보안에 좋지 않다.
  • 비밀번호 같은 민감한 정보는 RequestBody로 감싸서 보안을 해주는 게 좋다.

-RequestParam에서 Optional 사용하지 않는 걸 추천

  • @RequestParam은 기본적으로 required = true이기 때문에 null 값을 허용하지 않아 Optional로 감쌀 필요가 없다.
  • 만약 null 값이 있을 경우 애초에 이와 관련된 예외가 발생한다.

-Optional 사용할 때 .map(), .orElse() 의 적절한 사용 필요

  • Service에서 repository의 반환값에 .map()을 사용하여 responseDto를 만들어주고 값이 없으면 null을 반환하는데 이는 작업 수행 뒤에도 null을 반환하게 되서 적절한 위치에 사용한 것은 아님
  • 따라서 값이 없으면 예외를 던지는 .orElse 방식을 사용하는게 나음.

-null 체크를 할 때 .orElseThrow()를 사용

  • Optional 조회 후에 추가로 null을 체크하고 있는 부분은 비효율 적이므로 .orElseThrow()를 사용해서 바로 예외를 던진 후 나머지 로직을 수행하는 것이 깔끔할 것 같음

느낀 점 및 개선해야 할 점

 

이 과제를 하면서 어려웠던 점도 많고 사실상 공부를 시작하고 제일 복잡한 코드를 짜본건데, 시간 내에 기본 기능 구현을 했다는 점이 뿌듯한 것 같다. 코드를 짤 때 70%정도는 구글링의 도움을 받았는데, 조금씩 구글링 없이 혼자 더 생각해보는 시간을 많이 가져야겠다는 생각이 들었다.

이번에 코드를 짤 때 많이 알게 되고 몸소 느낀게 많은데 먼저 Repository를 interface와 class 두 개로 분리함으로써 데이터 접근 방식을 변경할 때 Service 코드를 수정할 필요가 없다는 점에서 코드 관리의 편리성이 증가한다는 점을 느끼게 되었고, 그 동안 공부를 하면서 CRUD가 기본적인 흐름이라는 것을 알고는 있었지만 계층을 나누고 데이터베이스까지 같이 생각을 하면서 코드를 짜보니 진짜 CRUD가 기본이 되야 하는구나를 체감하게 되었다.

지금 실력으로는 시간 안에 모든 단계의 코드를 짜는 것이 사실상 불가했는데, 조금 더 공부를 하고 코딩이 익숙해지면 기능을 추가해보면서 조금 더 관리가 편하고 탄탄한 구조의 코드를 설계해보는 것이 좋을 것 같다고 생각했다.

또, 피드백이 오고나서 헉 했던 부분이 많은데 비밀번호 기능에서 조회해서 id값을 알고 그 id 값을 파라미터에 넣어서 수정, 삭제를 하는게 맞나?라는 생각을 많이 했는데 RequestBody를 보고 아...이때 사용했어야 했구나를 깨달았다. 그리고 Optional과 HttpStatus가 헷갈리다고 했더니 자세하게 피드백을 주셔서 참고해서 조금 더 공부를 해야겠다고 다짐한 하루였다.