-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feat] 족보 생성 삭제 API #23
Changes from all commits
c5a6503
e7549bf
9373042
743dd91
22bbe3b
d4ab713
4eaf063
a19a7c8
40b0c2d
371d495
3439ded
45dbac4
6c61d84
74c14cf
ecf2c5a
7b1e057
200bf00
a98f15f
30ea548
766126a
98460dc
c9b5c08
147b3cc
af95019
c838a7a
9484aac
5cb42dc
5b557c4
035ce09
702a5f5
7ee6a4a
4200074
1e87ceb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package org.hankki.hankkiserver.api.favorite.controller; | ||
|
||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.hankki.hankkiserver.api.dto.HankkiResponse; | ||
import org.hankki.hankkiserver.api.favorite.controller.request.FavoriteDeleteRequest; | ||
import org.hankki.hankkiserver.api.favorite.service.FavoriteCommandService; | ||
import org.hankki.hankkiserver.api.favorite.service.command.FavoritePostCommand; | ||
import org.hankki.hankkiserver.api.favorite.controller.request.FavoritePostRequest; | ||
import org.hankki.hankkiserver.api.favorite.service.command.FavoritesDeleteCommand; | ||
import org.hankki.hankkiserver.auth.UserId; | ||
import org.hankki.hankkiserver.common.code.CommonSuccessCode; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/api/v1") | ||
public class FavoriteController { | ||
|
||
private final FavoriteCommandService favoriteCommandService; | ||
|
||
@PostMapping("/favorites") | ||
public HankkiResponse<Void> createFavorite(@UserId final Long userId, @RequestBody @Valid final FavoritePostRequest request) { | ||
|
||
favoriteCommandService.create(FavoritePostCommand.of(userId, request)); | ||
return HankkiResponse.success(CommonSuccessCode.CREATED); | ||
} | ||
|
||
@PostMapping("/favorites/batch-delete") | ||
public HankkiResponse<Void> deleteFavorite(@UserId final Long userId, @RequestBody final FavoriteDeleteRequest request) { | ||
|
||
favoriteCommandService.deleteFavorites(FavoritesDeleteCommand.of(userId, request)); | ||
return HankkiResponse.success(CommonSuccessCode.NO_CONTENT); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.hankki.hankkiserver.api.favorite.controller.request; | ||
|
||
import java.util.List; | ||
|
||
public record FavoriteDeleteRequest( | ||
List<Long> favoriteIds | ||
) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.hankki.hankkiserver.api.favorite.controller.request; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.Size; | ||
import java.util.List; | ||
|
||
public record FavoritePostRequest( | ||
@NotBlank(message = "제목이 비었습니다.") | ||
@Size(max = 18, message = "제목 길이가 18자를 초과했습니다.") | ||
String title, | ||
@Size(min = 1, max = 2, message = "해시태그 리스트 size가 1 이상 2 이하가 아닙니다.") | ||
List<@Size(min = 2, max= 10, message = "해시태그가 # 포함 10자를 초과했습니다.") String> details | ||
) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package org.hankki.hankkiserver.api.favorite.service; | ||
|
||
import jakarta.transaction.Transactional; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.hankki.hankkiserver.api.auth.service.UserFinder; | ||
import org.hankki.hankkiserver.api.favorite.service.command.FavoritesDeleteCommand; | ||
import org.hankki.hankkiserver.api.favoritestore.service.FavoriteStoreDeleter; | ||
import org.hankki.hankkiserver.common.code.UserErrorCode; | ||
import org.hankki.hankkiserver.common.exception.UnauthorizedException; | ||
import org.hankki.hankkiserver.domain.favorite.model.Favorite; | ||
import org.hankki.hankkiserver.api.favorite.service.command.FavoritePostCommand; | ||
import org.hankki.hankkiserver.domain.user.model.User; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class FavoriteCommandService { | ||
|
||
private final UserFinder userFinder; | ||
private final FavoriteFinder favoriteFinder; | ||
private final FavoriteUpdater favoriteUpdater; | ||
private final FavoriteStoreDeleter favoriteStoreDeleter; | ||
private final FavoriteDeleter favoriteDeleter; | ||
|
||
@Transactional | ||
public Long create(final FavoritePostCommand command) { | ||
|
||
User findUser = userFinder.getUser(command.userId()); | ||
String title = command.title(); | ||
String details = String.join(" ", command.details()); | ||
|
||
return favoriteUpdater.save(Favorite.create(findUser, title, details)); | ||
} | ||
|
||
@Transactional | ||
public void deleteFavorites(final FavoritesDeleteCommand command) { | ||
|
||
List<Favorite> favorites = favoriteFinder.findAllByIds(command.favoriteIds()); | ||
|
||
favorites.forEach(favorite -> { | ||
if (!favorite.getUser().getId().equals(command.userId())) { | ||
throw new UnauthorizedException(UserErrorCode.USER_FORBIDDEN); | ||
} | ||
}); | ||
|
||
favoriteStoreDeleter.deleteAllByFavorites(favorites); | ||
favoriteDeleter.deleteAll(favorites); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package org.hankki.hankkiserver.api.favorite.service; | ||
|
||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.hankki.hankkiserver.common.code.BusinessErrorCode; | ||
import org.hankki.hankkiserver.common.exception.InternalServerException; | ||
import org.hankki.hankkiserver.domain.favorite.model.Favorite; | ||
import org.hankki.hankkiserver.domain.favorite.repository.FavoriteRepository; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class FavoriteDeleter { | ||
|
||
private final FavoriteRepository favoriteRepository; | ||
|
||
protected void deleteAll(List<Favorite> favorites) { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 공백 맞춰주세요 |
||
try { | ||
favoriteRepository.deleteAll(favorites); | ||
} catch (Exception e) { | ||
throw new InternalServerException(BusinessErrorCode.INTERNAL_SERVER_ERROR); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package org.hankki.hankkiserver.api.favorite.service; | ||
|
||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.hankki.hankkiserver.common.code.FavoriteErrorCode; | ||
import org.hankki.hankkiserver.common.exception.NotFoundException; | ||
import org.hankki.hankkiserver.domain.favorite.model.Favorite; | ||
import org.hankki.hankkiserver.domain.favorite.repository.FavoriteRepository; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class FavoriteFinder { | ||
|
||
private final FavoriteRepository favoriteRepository; | ||
|
||
public Favorite findById(final Long id) { | ||
return favoriteRepository.findById(id).orElseThrow(() -> new NotFoundException(FavoriteErrorCode.FAVORITE_NOT_FOUND)); | ||
} | ||
|
||
public List<Favorite> findAllByIds(final List<Long> ids) { | ||
return favoriteRepository.findAllByIds(ids); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.hankki.hankkiserver.api.favorite.service; | ||
|
||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.hankki.hankkiserver.common.code.BusinessErrorCode; | ||
import org.hankki.hankkiserver.common.exception.InternalServerException; | ||
import org.hankki.hankkiserver.domain.favorite.model.Favorite; | ||
import org.hankki.hankkiserver.domain.favorite.repository.FavoriteRepository; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class FavoriteUpdater { | ||
|
||
private final FavoriteRepository favoriteRepository; | ||
|
||
protected Long save(Favorite favorite) { | ||
return favoriteRepository.save(favorite).getId(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.hankki.hankkiserver.api.favorite.service.command; | ||
|
||
import java.util.List; | ||
import org.hankki.hankkiserver.api.favorite.controller.request.FavoritePostRequest; | ||
|
||
public record FavoritePostCommand( | ||
Long userId, | ||
String title, | ||
List<String> details | ||
) { | ||
|
||
public static FavoritePostCommand of(final Long userId, final FavoritePostRequest favoritePostRequest) { | ||
|
||
return new FavoritePostCommand(userId, favoritePostRequest.title(), favoritePostRequest.details()); | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.hankki.hankkiserver.api.favorite.service.command; | ||
|
||
import java.util.List; | ||
import org.hankki.hankkiserver.api.favorite.controller.request.FavoriteDeleteRequest; | ||
|
||
public record FavoritesDeleteCommand( | ||
Long userId, | ||
List<Long> favoriteIds | ||
) { | ||
|
||
public static FavoritesDeleteCommand of(final Long userId, final FavoriteDeleteRequest favoriteDeleteRequest) { | ||
return new FavoritesDeleteCommand(userId, favoriteDeleteRequest.favoriteIds()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package org.hankki.hankkiserver.api.favoritestore.service; | ||
|
||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.hankki.hankkiserver.common.code.BusinessErrorCode; | ||
import org.hankki.hankkiserver.common.exception.InternalServerException; | ||
import org.hankki.hankkiserver.domain.favorite.model.Favorite; | ||
import org.hankki.hankkiserver.domain.favoritestore.repository.FavoriteStoreRepository; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class FavoriteStoreDeleter { | ||
|
||
private final FavoriteStoreRepository favoriteStoreRepository; | ||
|
||
public void deleteAllByFavorites(List<Favorite> favorites) { | ||
|
||
try { | ||
favoriteStoreRepository.deleteAllByFavorites(favorites); | ||
} catch (Exception e) { | ||
throw new InternalServerException(BusinessErrorCode.INTERNAL_SERVER_ERROR); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.hankki.hankkiserver.common.code; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum FavoriteErrorCode implements ErrorCode { | ||
|
||
FAVORITE_NOT_FOUND(HttpStatus.NOT_FOUND, "등록되지 않은 족보입니다."); | ||
|
||
private final HttpStatus httpStatus; | ||
private final String message; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.hankki.hankkiserver.common.code; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum FavoriteStoreErrorCode implements ErrorCode { | ||
|
||
FAVORITE_STORE_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 데이터입니다."); | ||
|
||
private final HttpStatus httpStatus; | ||
private final String message; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
package org.hankki.hankkiserver.domain.favorite.model; | ||
|
||
import jakarta.persistence.*; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import lombok.AccessLevel; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.hankki.hankkiserver.domain.common.BaseTimeEntity; | ||
import org.hankki.hankkiserver.domain.favoritestore.model.FavoriteStore; | ||
import org.hankki.hankkiserver.domain.user.model.User; | ||
|
||
@Entity | ||
|
@@ -27,6 +31,24 @@ public class Favorite extends BaseTimeEntity { | |
private String detail; | ||
|
||
@Column(nullable = false) | ||
private String favorite_image_url; | ||
|
||
private String image_url; | ||
|
||
@OneToMany(mappedBy = "favorite") | ||
private List<FavoriteStore> favoriteStores = new ArrayList<>(); | ||
|
||
public static Favorite create(User user, String name, String detail) { | ||
return Favorite.builder() | ||
.user(user) | ||
.name(name) | ||
.detail(detail) | ||
.build(); | ||
} | ||
|
||
@Builder | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 클래스 레벨에 @builder 작성해주면 해당 내용 없이도 builder 사용하실 수 있어요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저는 개인적으로 사용하는 필드들만 갖는 생성자 만든 후에 그 위에 @builder 붙이는 거 선호합니다. |
||
private Favorite(User user, String name, String detail) { | ||
this.user = user; | ||
this.name = name; | ||
this.detail = detail; | ||
this.image_url = "default.com"; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,18 @@ | ||
package org.hankki.hankkiserver.domain.favorite.repository; | ||
|
||
import java.util.List; | ||
import org.hankki.hankkiserver.domain.favorite.model.Favorite; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Modifying; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.repository.query.Param; | ||
|
||
public interface FavoriteRepository extends JpaRepository<Favorite, Long> { | ||
|
||
@Modifying | ||
@Query("delete from Favorite f where f in :favorites") | ||
void deleteAll(@Param("favorites") List<Favorite> favorites); | ||
|
||
@Query("select f from Favorite f where f.id in :favoriteId") | ||
List<Favorite> findAllByIds(@Param("favoriteId") List<Long> favoriteId); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,16 @@ | ||
package org.hankki.hankkiserver.domain.favoritestore.repository; | ||
|
||
import java.util.List; | ||
import org.hankki.hankkiserver.domain.favorite.model.Favorite; | ||
import org.hankki.hankkiserver.domain.favoritestore.model.FavoriteStore; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Modifying; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.repository.query.Param; | ||
|
||
public interface FavoriteStoreRepository extends JpaRepository<FavoriteStore, Long> { | ||
|
||
@Modifying | ||
@Query("delete from FavoriteStore fs where fs.favorite in :favorites") | ||
void deleteAllByFavorites(@Param("favorites")List<Favorite> favorites); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
원래는 201을 내려주면 Location 헤더에 resource의 위치를 포함시켜야 해서
저희 응답을 처리하는 advice에 추후 201상태 코드 가진 친구들에게 location header를 추가해주는 코드를 추가할 예정입니당.
이를 대비해서 create이후에 생성된 리소스의 pk 사용하지 않더라도 일단 갖고 있을 수 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Service return 타입을 Long으로 변경하고
return favoriteRepository.save(Favorite.create(findUser, title, details)).getId();
으로 변경하겠습니다.