많은 요리 애호가들이 자주 겪는 상황이 있습니다. 냉장고에 있는 특정 재료를 사용해야 하는데, 그 재료로 어떤 요리를 만들 수 있을지 고민되는 경우죠. 예를 들어, 굴소스가 있다면 알리오올리오 뿐만 아니라 다양한 요리에 활용할 수 있습니다. 이런 필요를 해결하기 위해 특정 재료를 선택했을 때 해당 재료로 만들 수 있는 모든 레시피를 조회하는 기능을 Spring Boot로 구현하는 방법을 알아보겠습니다.
데이터 모델링: 효율적인 구조 설계
모든 재료를 하나씩 클래스로 만들 필요는 없습니다. 대신 효율적인 데이터 모델링을 통해 유연한 시스템을 구축할 수 있습니다.
엔티티 설계의 핵심
Ingredient(재료) 엔티티: 재료의 기본 정보를 저장
Recipe(레시피) 엔티티: 레시피의 상세 정보를 관리
다대다 관계 설정: 하나의 재료가 여러 레시피에, 하나의 레시피가 여러 재료에 사용될 수 있는 관계
java
@Entity
public class Ingredient {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(mappedBy = "ingredients")
private List<Recipe> recipes;
}
@Entity
public class Recipe {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String instructions;
@ManyToMany
@JoinTable(
name = "recipe_ingredient",
joinColumns = @JoinColumn(name = "recipe_id"),
inverseJoinColumns = @JoinColumn(name = "ingredient_id")
)
private List<Ingredient> ingredients;
}
검색 기능 구현: 재료 기반 레시피 조회
Repository 계층 구현
java
public interface RecipeRepository extends JpaRepository<Recipe, Long> {
List findByIngredients_NameContaining(String name);
List findByIngredients_NameIn(List ingredientNames);
}
Service 계층 구현
java
@Service
@RequiredArgsConstructor
public class RecipeService {
private final RecipeRepository recipeRepository;
public List<Recipe> findRecipesByIngredient(String ingredientName) {
return recipeRepository.findByIngredients_NameContaining(ingredientName);
}
public List<Recipe> findRecipesByMultipleIngredients(List<String> ingredientNames) {
return recipeRepository.findByIngredients_NameIn(ingredientNames);
}
}
Controller 계층 구현
java
@RestController
@RequestMapping("/api/recipes")
@RequiredArgsConstructor
public class RecipeController {
private final RecipeService recipeService;
@GetMapping("/search")
public ResponseEntity<List<Recipe>> searchRecipesByIngredient(
@RequestParam String ingredient) {
List<Recipe> recipes = recipeService.findRecipesByIngredient(ingredient);
return ResponseEntity.ok(recipes);
}
@GetMapping("/search/multiple")
public ResponseEntity<List<Recipe>> searchRecipesByMultipleIngredients(
@RequestParam List<String> ingredients) {
List<Recipe> recipes = recipeService.findRecipesByMultipleIngredients(ingredients);
return ResponseEntity.ok(recipes);
}
}
실제 적용 예시
사용자가 "굴소스"를 검색하면:
text
GET /api/recipes/search?ingredient=굴소스
사용자가 여러 재료를 동시에 검색하면:
text
GET /api/recipes/search/multiple?ingredients=굴소스&ingredients=마늘&ingredients=새우
고급 기능 확장
정확도 순 정렬: 재료 매칭 개수가 많은 레시피를 우선 표시
카테고리 필터링: 메인요리, 후식, 안주 등 카테고리별 필터링
난이도 필터: 초보자, 중급자, 전문가별 난이도 설정
소요 시간 필터: 10분 이하, 30분 이하 등 조리 시간 기준 필터링
구현 시 고려사항
데이터 초기화: 애플리케이션 시작 시 기본 재료와 레시피 데이터를 자동으로 입력
성능 최적화: 자주 검색되는 재료에 대한 캐싱 전략 구현
유사 재료 매칭: "간장"과 "진간장" 같은 유사 재료 연관 검색
사용자 기반 추천: 사용자의 검색 이력을 기반으로 개인화된 추천
결론
Spring Boot와 JPA를 활용하면 특정 재료를 기반으로 레시피를 검색하는 기능을 효율적으로 구현할 수 있습니다. 모든 재료를 개별 클래스로 만들 필요 없이, 적절한 데이터 모델링과 관계 설정을 통해 확장성 있는 시스템을 구축할 수 있습니다. 이렇게 구현된 시스템은 사용자가 가지고 있는 재료를 최대한 활용할 수 있도록 도와주며, 다양한 요리 아이디어를 제공하는 유용한 서비스가 될 수 있습니다.
이러한 기능은 단순한 레시피 검색을 넘어서 사용자의 식재료 낭비를 줄이고, 창의적인 요리 시도를 장려하는 의미 있는 서비스로 발전시킬 수 있습니다.
더 자세한 정보는 https://pedircitasdni.es/ 에서 확인하세요.