added delete favorite api call

This commit is contained in:
durn
2026-03-03 23:59:07 -07:00
parent d03cbaf9a3
commit 0a38aa3ded
7 changed files with 157 additions and 21 deletions
@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.example.demo.dto.UserDto;
import com.example.demo.entity.User; import com.example.demo.entity.User;
import com.example.demo.service.UserService; import com.example.demo.service.UserService;
@@ -36,22 +37,31 @@ public class UserController {
//build get all users REST API //build get all users REST API
@GetMapping @GetMapping
public List<User> getAllUsers(){ public List<UserDto> getAllUsers(){
return userService.getAllUsers(); return userService.getAllUsers();
} }
//build get user by id REST API //build get user by id REST API
// http://localhost:8080/api/users/(id number goes here) // http://localhost:8080/api/users/(id number goes here)
@GetMapping("{id}") @GetMapping("{id}")
public ResponseEntity<User> getUserById(@PathVariable("id") Integer userId){ public ResponseEntity<UserDto> getUserById(@PathVariable("id") Integer userId){
return new ResponseEntity<User>(userService.getUserById(userId), HttpStatus.OK); return new ResponseEntity<UserDto>(userService.getUserById(userId), HttpStatus.OK);
}
//build create favorite REST API
@PostMapping("/{userId}/favorites/{recipeId}")
public ResponseEntity<UserDto> saveFavorite( @PathVariable Integer userId, @PathVariable Integer recipeId) {
UserDto updatedUser = userService.saveFavorite(userId, recipeId);
return new ResponseEntity<>(updatedUser, HttpStatus.OK);
} }
//build update user REST API //build update user REST API
// http://localhost:8080/api/users/(id number goes here) // http://localhost:8080/api/users/(id number goes here)
@PutMapping("{id}") @PutMapping("{id}")
public ResponseEntity<User> updateUser(@PathVariable("id") Integer userId, @RequestBody User user){ public ResponseEntity<UserDto> updateUser(@PathVariable("id") Integer userId, @RequestBody User user){
return new ResponseEntity<User>(userService.updateUser(user, userId), HttpStatus.OK); return new ResponseEntity<UserDto>(userService.updateUser(user, userId), HttpStatus.OK);
} }
//build delete user REST API //build delete user REST API
@@ -60,5 +70,13 @@ public class UserController {
userService.deleteUser(userId); userService.deleteUser(userId);
return new ResponseEntity<String>("User deleted succesfully!", HttpStatus.OK); return new ResponseEntity<String>("User deleted succesfully!", HttpStatus.OK);
} }
//build delete favorite REST API
@DeleteMapping("/{userId}/favorites/{recipeId}")
public ResponseEntity<String> deleteFavorite( @PathVariable Integer userId, @PathVariable Integer recipeId) {
userService.deleteFavorite(userId, recipeId);
return new ResponseEntity<String>("Favorite deleted succesfully!", HttpStatus.OK);
}
} }
@@ -2,11 +2,15 @@ package com.example.demo.dto;
public class UserDto { public class UserDto {
private Integer id; private Integer id;
private String username;
private String email;
public UserDto() {} public UserDto() {}
public UserDto(Integer id) { public UserDto(Integer id, String username, String email) {
this.id = id; this.id = id;
this.username = username;
this.email = email;
} }
public Integer getId() { public Integer getId() {
@@ -16,4 +20,22 @@ public class UserDto {
public void setId(Integer id) { public void setId(Integer id) {
this.id = id; this.id = id;
} }
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
} }
@@ -54,6 +54,10 @@ public class Recipe {
joinColumns = {@JoinColumn(name = "recipe_id")}, joinColumns = {@JoinColumn(name = "recipe_id")},
inverseJoinColumns = {@JoinColumn(name = "tag_id")}) inverseJoinColumns = {@JoinColumn(name = "tag_id")})
private Set<Tag> tags = new HashSet<>(); private Set<Tag> tags = new HashSet<>();
// User is the manager for this relationship
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "FavRecipes")
private Set<User> users = new HashSet<>();
// Default constructor // Default constructor
@@ -161,6 +165,14 @@ public class Recipe {
public void setTags(Set<Tag> tags) { public void setTags(Set<Tag> tags) {
this.tags = tags; this.tags = tags;
} }
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
@@ -4,6 +4,9 @@ import jakarta.persistence.Entity;
import jakarta.persistence.FetchType; import jakarta.persistence.FetchType;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType; import jakarta.persistence.GenerationType;
@@ -37,6 +40,13 @@ public class User {
// User Recipe relationship // User Recipe relationship
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<Recipe> recipes = new HashSet<>(); private Set<Recipe> recipes = new HashSet<>();
// Favorite relationship and also junction table
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "favorites",
joinColumns = {@JoinColumn(name = "userId")},
inverseJoinColumns = {@JoinColumn(name = "recipeId")})
private Set<Recipe> FavRecipes = new HashSet<>();
// Constructors // Constructors
public User() {} public User() {}
@@ -67,4 +77,14 @@ public class User {
public LocalDateTime getCreatedAt() { return createdAt; } public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; } public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public Set<Recipe> getFavRecipes() {
return FavRecipes;
}
public void setFavRecipes(Set<Recipe> favRecipes) {
FavRecipes = favRecipes;
}
} }
@@ -82,7 +82,7 @@ private TagRepo tagRepository;
)) ))
.toList(); .toList();
UserDto userDto = new UserDto(recipe.getUser().getId()); UserDto userDto = new UserDto(recipe.getUser().getId(), recipe.getUser().getUsername(), recipe.getUser().getEmail());
return new RecipeDto( return new RecipeDto(
recipe.getTitle(), recipe.getTitle(),
@@ -1,23 +1,44 @@
package com.example.demo.service.Impl; package com.example.demo.service.Impl;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.example.demo.dto.ImageDto;
import com.example.demo.dto.RecipeDto;
import com.example.demo.dto.RecipeIngredientDto;
import com.example.demo.dto.StepDto;
import com.example.demo.dto.TagDto;
import com.example.demo.dto.UserDto;
import com.example.demo.entity.Recipe;
import com.example.demo.entity.User; import com.example.demo.entity.User;
import com.example.demo.exception.NotFoundException; import com.example.demo.exception.NotFoundException;
import com.example.demo.repository.RecipeRepo;
import com.example.demo.repository.UserRepo; import com.example.demo.repository.UserRepo;
import com.example.demo.service.UserService; import com.example.demo.service.UserService;
import jakarta.transaction.Transactional;
@Service @Service
public class UserServiceImpl implements UserService{ public class UserServiceImpl implements UserService{
private UserRepo userRepository; private UserRepo userRepository;
private RecipeRepo recipeRepository;
public UserServiceImpl(UserRepo userRepository) { public UserServiceImpl(UserRepo userRepository, RecipeRepo recipeRepository) {
super(); super();
this.userRepository = userRepository; this.userRepository = userRepository;
this.recipeRepository = recipeRepository;
}
public UserDto convertToDto(User user) {
return new UserDto(
user.getId(),
user.getUsername(),
user.getEmail()
);
} }
@Override @Override
@@ -26,19 +47,42 @@ public class UserServiceImpl implements UserService{
} }
@Override @Override
public List<User> getAllUsers() { public List<UserDto> getAllUsers() {
return userRepository.findAll();
}
@Override
public User getUserById(Integer Id) {
return userRepository.findById(Id).orElseThrow(() -> List<UserDto> list = new ArrayList<>();
new NotFoundException("User", "id", Id)); for (User user : userRepository.findAll()) {
UserDto userDto = convertToDto(user);
list.add(userDto);
}
return list;
} }
@Override @Override
public User updateUser(User user, Integer Id) { public UserDto getUserById(Integer Id) {
return convertToDto(userRepository.findById(Id).orElseThrow(() ->
new NotFoundException("User", "id", Id)));
}
@Override
@Transactional
public UserDto saveFavorite(Integer userId, Integer recipeId) {
User existingUser = userRepository.findById(userId).orElseThrow(
() -> new NotFoundException("User", "id", userId));
Recipe existingRecipe = recipeRepository.findById(recipeId).orElseThrow(
() -> new NotFoundException("Recipe", "id", recipeId));
existingUser.getFavRecipes().add(existingRecipe);
userRepository.save(existingUser);
return convertToDto(existingUser);
}
@Override
public UserDto updateUser(User user, Integer Id) {
User existingUser = userRepository.findById(Id).orElseThrow( User existingUser = userRepository.findById(Id).orElseThrow(
() -> new NotFoundException("User", "id", Id)); () -> new NotFoundException("User", "id", Id));
@@ -48,7 +92,7 @@ public class UserServiceImpl implements UserService{
userRepository.save(existingUser); userRepository.save(existingUser);
return existingUser; return convertToDto(existingUser);
} }
@Override @Override
@@ -58,4 +102,20 @@ public class UserServiceImpl implements UserService{
userRepository.deleteById(Id); userRepository.deleteById(Id);
} }
@Override
@Transactional
public void deleteFavorite(Integer userId, Integer recipeId) {
User existingUser = userRepository.findById(userId).orElseThrow(
() -> new NotFoundException("User", "id", userId));
Recipe existingRecipe = recipeRepository.findById(recipeId).orElseThrow(
() -> new NotFoundException("Recipe", "id", recipeId));
userRepository.save(existingUser);
existingUser.getFavRecipes().remove(existingRecipe);
}
} }
@@ -2,12 +2,16 @@ package com.example.demo.service;
import java.util.List; import java.util.List;
import com.example.demo.dto.UserDto;
import com.example.demo.entity.User; import com.example.demo.entity.User;
public interface UserService { public interface UserService {
UserDto convertToDto(User user);
User saveUser(User user); User saveUser(User user);
List<User> getAllUsers(); List<UserDto> getAllUsers();
User getUserById(Integer Id); UserDto getUserById(Integer Id);
User updateUser(User user, Integer Id); UserDto saveFavorite(Integer userId, Integer recipeId);
UserDto updateUser(User user, Integer Id);
void deleteUser(Integer Id); void deleteUser(Integer Id);
void deleteFavorite(Integer userId, Integer recipeId);
} }