개발 프로젝트/[팀 프로젝트] 냉파마스터

냉장고 재료 CRUD 및 사용 처리 API 구현

namerong 2026. 6. 28. 00:57

작업 개요

냉장고 재료 관리 기능을 구현했다.
냉장고 화면에서 사용자가 재료를 등록하고, 조회하고, 수정하고, 삭제하고, 사용 처리할 수 있도록 하는 API 구현이 중심이었다.

진행한 이슈는 다음과 같다.

#16 냉장고 재료 등록 API 구현
#17 냉장고 재료 목록/카테고리별 조회 API 구현
#18 냉장고 재료 수정 API 구현
#19 냉장고 재료 삭제 API 구현
#20 냉장고 재료 전부 사용 처리 API 구현
#21 냉장고 재료 일부 사용 처리 API 구현

구현 배경

냉장고 재료 기능은 사용자가 직접 보유 중인 재료를 관리하는 기능이다.
단순히 재료를 저장하는 것뿐 아니라, 사전 재료 정보와 연결해서 재료명, 카테고리, 유통기한, 수량 등을 함께 관리해야 했다.

특히 냉장고 재료 테이블에는 실제 재료명이 저장되지 않고 productId가 저장된다.
따라서 목록 조회 시에는 fridge_items와 products 정보를 함께 사용해야 했다.

fridge_items
-> 사용자가 보유한 냉장고 재료 정보

products
-> 사전 재료 정보

구현 내용

냉장고 재료 등록

냉장고 재료 등록 API는 로그인한 사용자의 냉장고에 재료를 추가하는 기능이다.

요청값은 다음과 같다.

productId
quantity
expiryDate
memo

등록 시에는 먼저 로그인한 사용자를 확인하고, 요청으로 들어온 productId가 실제 존재하는 사전 재료인지 검증했다.

email로 member 조회
-> productId 유효성 검증
-> fridge_items 저장

사전 재료 검증은 기존에 구현한 ProductService.validateExists()를 재사용했다.

냉장고 재료 목록 조회

냉장고 재료 목록 조회는 로그인한 사용자의 삭제되지 않은 재료만 반환하도록 구현했다.

GET /api/v1/fridge-items

조회 조건은 다음과 같다.

memberId 일치
isDeleted = false

응답에는 냉장고 재료 정보뿐 아니라 사전 재료의 이름과 카테고리 정보도 포함했다.

fridgeItemId
productId
productCategoryId
productName
quantity
expiryDate
memo

냉장고 재료 카테고리별 조회

카테고리별 조회는 다음 API로 구현했다.

GET /api/v1/fridge-items/categories/{categoryId}

fridge_items에는 카테고리 ID가 직접 없기 때문에, 먼저 products에서 해당 카테고리의 재료 ID 목록을 찾고 그 ID를 기준으로 냉장고 재료를 조회했다.

categoryId로 products 조회
-> productId 목록 추출
-> memberId와 productId 목록으로 fridge_items 조회

냉장고 재료 수정

냉장고 재료 수정 API는 기존 냉장고 재료의 재료, 수량, 유통기한, 메모를 수정하는 기능이다.

PATCH /api/v1/fridge-items/{fridgeItemId}

수정 시에는 다음 조건으로 재료를 조회했다.

fridgeItemId 일치
memberId 일치
isDeleted = false

이 조건을 통해 다른 사용자의 냉장고 재료를 수정하거나, 이미 삭제된 재료를 수정하는 상황을 막았다.

냉장고 재료 삭제

냉장고 재료 삭제는 물리 삭제가 아니라 soft delete 방식으로 구현했다.

DELETE /api/v1/fridge-items/{fridgeItemId}

삭제 시 실제 row를 제거하지 않고 다음 값을 변경했다.

isDeleted = true
deletedAt = 현재 시간
updatedAt = 현재 시간

목록 조회에서는 isDeleted = false 조건을 사용하기 때문에 삭제된 재료는 조회되지 않는다.

냉장고 재료 전부 사용 처리

전부 사용 처리 API는 사용자가 특정 냉장고 재료를 모두 사용했을 때 호출하는 기능이다.

PATCH /api/v1/fridge-items/{fridgeItemId}/use-all

현재 DB에는 별도의 사용 이력 테이블이나 사용 수량 컬럼이 없기 때문에, 전부 사용 처리는 목록에서 제외되도록 soft delete와 같은 방식으로 처리했다.

다만 의미를 분리하기 위해 엔티티에는 useAll() 메서드를 따로 두었다.

useAll()
-> delete()

냉장고 재료 일부 사용 처리

일부 사용 처리 API는 재료를 일부 사용한 뒤 남은 수량을 갱신하는 기능이다.

PATCH /api/v1/fridge-items/{fridgeItemId}/use-partial

냉장고 재료의 수량은 숫자가 아니라 문자열로 저장된다.

1개
200g
반 개
조금

따라서 백엔드에서 수량을 직접 계산하지 않고, 사용 후 남은 수량을 요청값으로 받아 저장하는 방식으로 구현했다.

요청 예시는 다음과 같다.

{
  "quantity": "2개"
}

테스트

서비스 테스트는 각 기능의 정상 흐름을 기준으로 작성했다.

테스트한 내용은 다음과 같다.

냉장고 재료 등록 시 응답 반환 확인
냉장고 재료 목록 조회 시 삭제되지 않은 내 재료만 반환 확인
카테고리별 조회 시 해당 카테고리 재료만 반환 확인
냉장고 재료 수정 시 수정된 값 반환 확인
냉장고 재료 삭제 시 목록 조회에서 제외되는지 확인
냉장고 재료 전부 사용 처리 시 목록 조회에서 제외되는지 확인
냉장고 재료 일부 사용 처리 시 남은 수량으로 변경되는지 확인

삭제와 전부 사용 처리는 응답값보다 이후 목록에서 제외되는지가 중요했다.
그래서 삭제 또는 전부 사용 처리 후 다시 목록을 조회하고, 해당 fridgeItemId가 포함되지 않는지 검증했다.

API 확인

Postman으로 다음 API를 확인했다.

POST /api/v1/fridge-items
GET /api/v1/fridge-items
GET /api/v1/fridge-items/categories/{categoryId}
PATCH /api/v1/fridge-items/{fridgeItemId}
DELETE /api/v1/fridge-items/{fridgeItemId}
PATCH /api/v1/fridge-items/{fridgeItemId}/use-all
PATCH /api/v1/fridge-items/{fridgeItemId}/use-partial

인증 토큰 없이 요청했을 때 401 Unauthorized가 반환되는 것도 확인했다.

정리

이번 작업을 통해 냉장고 재료 관리의 기본 흐름을 구현했다.

등록
조회
카테고리별 조회
수정
삭제
전부 사용 처리
일부 사용 처리

이번 구현에서 가장 중요했던 부분은 냉장고 재료와 사전 재료의 관계를 분리해서 이해하는 것이었다.

fridge_items는 사용자가 보유한 재료 정보를 담고, products는 사전 재료 정보를 담는다.
따라서 목록 조회 응답을 만들 때는 두 데이터를 함께 사용해야 했다.

또한 삭제와 전부 사용 처리는 현재 동작은 비슷하지만 의미가 다르기 때문에 메서드를 분리했다.
이후 사용 이력이나 통계 기능이 추가될 경우 useAll() 쪽을 확장하면 된다.