8월 24일부터 31일까지 프로그래머스 1차 프로젝트를 진행했다.
모든 팀이 동일한 주제로 프로젝트를 진행했기 때문에, 같은 요구사항을 어떻게 설계하고 구현하는지가 중요했다.
이번 프로젝트에서 나는 공통 예외 처리, 주문 내역 조회 및 페이지네이션, 이메일 기반 주문 조회, 이메일 확인 기능, 상품 검색 기능을 담당했다.
공통 예외 처리
프로젝트 초반에는 여러 API에서 발생하는 예외를 일관된 형태로 처리할 수 있도록 공통 예외 처리 구조를 구현했다.
ApiException을 만들어 HTTP 상태 코드와 에러 코드를 함께 관리하고, GlobalExceptionHandler에서 해당 예외를 한 곳에서 처리하도록 구성했다. 클라이언트에는 code, message, timestamp를 포함한 ErrorResponse를 반환하도록 했다.
이를 통해 각 Controller에서 예외 처리 코드를 반복해서 작성하지 않아도 되었고, API마다 동일한 형식으로 에러를 전달할 수 있었다.
처음에는 기능 구현에 집중하다 보니 예외 처리를 각각의 기능 안에서 처리할 수도 있었지만, 프로젝트 전체에서 공통적으로 사용되는 부분을 별도로 분리하면서 공통 기능은 한 곳에서 관리하는 것이 유지보수에 유리하다는 점을 배웠다.
주문 내역 조회 및 페이지네이션
다음으로 주문 내역 조회 기능과 페이지네이션을 구현했다.
주문 목록을 한 번에 모두 가져오는 대신 Spring Data JPA의 Page와 Pageable을 활용해 서버에서 페이지 단위로 데이터를 조회하도록 구현했다.
관리자 주문 목록은 한 페이지에 10개의 주문이 표시되도록 설정하고, 최신 주문이 먼저 보이도록 orderDate를 기준으로 내림차순 정렬했다.
조회한 Page<Order>에서 필요한 데이터만 OrderResponse로 변환하고, 전체 페이지 수와 함께 응답하도록 구성했다.
이 기능을 구현하면서 단순히 데이터를 조회하는 것뿐만 아니라 실제 화면에서 데이터를 어떻게 보여줄지까지 고려해 API의 응답 형태를 설계하는 것이 중요하다는 점을 알게 되었다.
이메일 기반 주문 조회
고객의 주문 내역을 이메일을 기준으로 조회하는 기능도 구현했다.
먼저 existsByEmail()을 이용해 해당 이메일로 주문한 내역이 존재하는지 확인하고, 존재하지 않는 경우 ApiException을 발생시켜 사용자에게 오류를 전달하도록 했다.
주문 내역 조회 역시 Page와 Pageable을 활용해 페이지네이션을 적용했고, 최신 주문부터 확인할 수 있도록 주문일을 기준으로 내림차순 정렬했다.
이 기능을 구현하면서 관리자용 전체 주문 조회와 고객용 이메일 주문 조회가 비슷한 구조를 가지고 있다는 점을 확인했고, 같은 패턴을 활용하면서도 각각의 요구사항에 맞게 구현할 수 있었다.
이메일 확인 기능
주문 내역을 조회하기 전에 해당 이메일로 주문한 기록이 있는지 확인할 수 있도록 이메일 확인 API도 구현했다.
Repository의 existsByEmail()을 활용해 데이터의 존재 여부만 확인하고 Boolean으로 반환하도록 구성했다.
전체 주문 데이터를 조회하는 것이 아니라 존재 여부만 필요한 경우 existsByEmail()을 사용하는 것이 더 적절하다는 점을 배울 수 있었다.
상품 검색 기능
상품 목록 조회 API에 상품명 검색 기능을 추가했다.
기존 상품 목록 조회에 페이지네이션과 가격 정렬 기능이 있었기 때문에, 여기에 productName을 검색 조건으로 추가했다.
검색어가 없으면 기존처럼 전체 상품을 조회하고, 검색어가 입력된 경우 Repository의
findDistinctByNameContaining()
을 사용해 상품명에 검색어가 포함된 상품을 조회하도록 구현했다.
여기서 Containing을 사용해 상품명에 검색어가 포함되어 있는지를 기준으로 검색할 수 있도록 했고, Distinct를 사용해 중복된 결과가 반환되지 않도록 했다.
또한 검색 기능과 함께 가격 오름차순·내림차순 정렬과 페이지네이션이 함께 동작하도록 구현했다.
이 과정에서 Repository 메서드 이름만으로도 원하는 조회 조건을 표현할 수 있는 Spring Data JPA의 쿼리 메서드 방식을 직접 활용해볼 수 있었다.
프로젝트를 진행하며 배운 점
이번 프로젝트를 통해 단순히 기능을 구현하는 것보다 기능을 어떻게 나누고 서로 연결할지 설계하는 과정이 중요하다는 점을 배웠다.
특히 Controller, Service, Repository의 역할을 구분하고 공통 예외 처리를 별도로 관리하면서 각 계층의 책임을 명확하게 하는 경험을 할 수 있었다.
또한 페이지네이션을 구현하면서 Page와 Pageable을 활용하는 방법을 익혔고, Repository의 existsByEmail()이나 findDistinctByNameContaining()과 같은 Spring Data JPA의 기능을 실제 프로젝트에 적용해볼 수 있었다.
팀 프로젝트를 진행하면서는 내가 맡은 기능만 구현하는 것이 아니라 다른 팀원의 기능과 어떻게 연결되는지 고려하면서 개발하는 것도 중요하다는 것을 느꼈다. API의 요청과 응답 형태를 맞추고, 프론트엔드와 연동하면서 서로 필요한 부분을 계속 확인하는 과정이 필요했다.
아쉬웠던 점과 개선할 점
이번 프로젝트에서 가장 아쉬웠던 부분은 Entity를 설계할 때 데이터의 수정이나 삭제가 기존 데이터에 미치는 영향까지 충분히 고려하지 못했던 점이다.
실제로 상품 가격을 수정했을 때 기존 주문의 결제 금액이나 매출 통계에도 영향을 주었고, 상품을 삭제했을 때는 기존 주문 내역에서 해당 상품이 보이지 않는 문제가 발생했다.
이후 다른 팀의 구현을 보면서, 주문 당시의 결제 금액을 Order에 별도로 저장하거나 상품과 주문 데이터를 바로 삭제하지 않고 Flag를 사용해 삭제 여부를 관리하는 방식을 알게 되었다. 이를 통해 과거의 주문 데이터는 당시의 상태 그대로 보존하면서 상품의 현재 상태도 별도로 관리할 수 있다는 점을 배웠다.
처음부터 이런 데이터의 변경과 삭제에 따른 영향을 고려해 Entity를 설계했다면 더 안정적인 구조를 만들 수 있었을 것 같아 아쉬움이 남는다. 다음 프로젝트에서는 단순히 현재 기능이 정상적으로 동작하는 것뿐만 아니라, 데이터가 변경되거나 삭제된 이후에도 기존 데이터가 올바르게 유지되는지까지 고려하여 Entity를 설계하고 싶다.
마무리
8월 24일부터 31일까지 진행한 1차 프로젝트를 통해 Spring Boot와 JPA를 이용해 실제 요구사항을 API로 구현하고, 프론트엔드와 연동하는 전체적인 개발 과정을 경험할 수 있었다.
특히 이번 프로젝트에서는 공통 예외 처리부터 주문 조회, 페이지네이션, 이메일 조회, 상품 검색까지 직접 구현하면서 Spring Data JPA를 실제 프로젝트에 적용해본 경험이 가장 큰 수확이었다.
짧은 기간 동안 팀원들과 하나의 서비스를 완성하는 과정에서 기능 구현뿐만 아니라 협업과 코드 리뷰, API 연동의 중요성도 함께 경험할 수 있었다.
이번 프로젝트에서 부족했던 부분은 다음 프로젝트에서 보완하면서, 단순히 동작하는 코드를 작성하는 것을 넘어 유지보수하기 좋은 구조와 안정적인 기능을 구현할 수 있는 개발자가 되는 것을 목표로 하고 싶다.
Github 링크
https://github.com/prgrms-be-devcourse/NBE-14-1-YUKGAEJANG
PPT
'회고 > 프로그래머스 데브코스' 카테고리의 다른 글
| 백엔드 데브코스 12기 37일차 (0) | 2026.09.02 |
|---|---|
| 백엔드 데브코스 12기 36일차 (0) | 2026.08.31 |
| 백엔드 데브코스 12기 35일차 (0) | 2026.08.30 |
| 백엔드 데브코스 12기 34일차 (0) | 2026.08.27 |
| 백엔드 데브코스 12기 33일차 (0) | 2026.08.26 |
댓글