SpringBoot
[instagramProject] 인스타 팔로우 / 좋아요 기능 구현
유쾌한고등어
2023. 3. 5. 18:00
● 팔로우 기능 구현
1. FollowController
- 팔로우 토글 기능 구현
- 클라이언트 요청에 따라 팔로우,언팔로우 개별 api 구현
// FollowController.java
@RequestMapping("/app")
@RestController
public class FollowController {
private final FollowService followService;
private final UserService userService;
private final JwtService jwtService;
@Autowired
public FollowController(FollowService followService, UserService userService,
JwtService jwtService) {
this.followService = followService;
this.userService = userService;
this.jwtService = jwtService;
}
@PostMapping("/follow/postfollow/{toUserId}")
public BaseResponse<?> PostFollow(@PathVariable("toUserId") long toUserId)
throws BaseException{
try{
if (!userService.checkUserExist(toUserId)){
return new BaseResponse<>(USER_ID_NOT_EXIST);
}
Long fromUserId = jwtService.getUserIdx();
if(toUserId==fromUserId){
return new BaseResponse<>(USER_ID_CANNOT_FOLLOW);
}
if(followService.checkFollow(fromUserId,toUserId)==1){
return new BaseResponse<>(USER_ID_FOLLOW_EXISTS);
}else{
followService.follow(fromUserId,toUserId);
return new BaseResponse<>("구독을 완료했습니다.");
}
}catch (BaseException exception) {
return new BaseResponse<>((exception.getStatus()));
}
}
@PostMapping("/follow/postunfollow/{toUserId}")
public BaseResponse<?> PostUnFollow(@PathVariable("toUserId") long toUserId)
throws BaseException{
try{
if (!userService.checkUserExist(toUserId)){
return new BaseResponse<>(USER_ID_NOT_EXIST);
}
Long fromUserId = jwtService.getUserIdx();
if(toUserId==fromUserId){
return new BaseResponse<>(USER_ID_CANNOT_FOLLOW);
}
if(followService.checkFollow(fromUserId,toUserId)==1){
followService.unFollow(fromUserId,toUserId);
return new BaseResponse<>("구독취소를 완료했습니다.");
}else{
return new BaseResponse<>(USER_ID_UNFOLLOW_EXISTS);
}
}catch (BaseException exception) {
return new BaseResponse<>((exception.getStatus()));
}
}
@PostMapping("/follow/{toUserId}")
public BaseResponse<?> FollowToggle(@PathVariable("toUserId") long toUserId)
throws BaseException {
if (!userService.checkUserExist(toUserId)){
return new BaseResponse<>(USER_ID_NOT_EXIST);
}
try{
Long fromUserId = jwtService.getUserIdx();
if(toUserId==fromUserId){
return new BaseResponse<>(USER_ID_CANNOT_FOLLOW);
}
String returnMessage = (followService.checkFollow(fromUserId,toUserId)==1)?
"id:"+ fromUserId + "님이 " + "id:" + toUserId + "님을 구독취소했습니다.":
"id:" + fromUserId + "님이 " + "id:"+toUserId + "님을 구독했습니다.";
if(followService.checkFollow(fromUserId,toUserId)==1){
followService.unFollow(fromUserId,toUserId);
}else{
followService.follow(fromUserId,toUserId);
}
FollowDto followDto = new FollowDto(fromUserId,toUserId);
return new BaseResponse<>(returnMessage,followDto);
}catch (BaseException exception) {
return new BaseResponse<>((exception.getStatus()));
}
}
}
2. FollowService 구현
// FollowService.java
@RequiredArgsConstructor
@Service
public class FollowService {
private final FollowRepository followRepository;
@Transactional
public void follow(long fromUserId,long toUserId){
followRepository.mFollow(fromUserId,toUserId);
}
@Transactional
public void unFollow(Long fromUserId,Long toUserId){
followRepository.mUnFollow(fromUserId,toUserId);
}
@Transactional
public int checkFollow(Long fromUserId, Long toUserId) {
return followRepository.checkFollow(fromUserId,toUserId);
}
}
3. FollowRepo 구현
public interface FollowRepository extends JpaRepository<Follow,Long> {
@Modifying
@Query(value="INSERT INTO Follow(fromUserId,toUserId,createdAt,status,updatedAt) VALUES(:fromUserId,:toUserId,now(),'ACTIVE',now())",nativeQuery = true)
void mFollow(long fromUserId,long toUserId);
@Modifying
@Query(value = "DELETE FROM Follow WHERE fromUserId = :fromUserId AND toUserId =:toUserId",nativeQuery = true)
void mUnFollow(Long fromUserId,Long toUserId);
@Query(value = "SELECT EXISTS(select * from Follow where fromUserId=:fromUserId and toUserId = :toUserId)",nativeQuery = true)
int checkFollow(Long fromUserId, Long toUserId);
@Query(value = "SELECT COUNT(*) FROM Follow WHERE fromUserId = :principalId AND toUserId = :pageUserId",nativeQuery = true)
int followState(long principalId,long pageUserId);
@Query(value = "SELECT COUNT(*) FROM Follow WHERE fromUserId=:pageUserId",nativeQuery = true)
int followingCount(long pageUserId);
@Query(value = "SELECT COUNT(*) FROM Follow WHERE toUserId=:pageUserId",nativeQuery = true)
int followerCount(long pageUserId);
}
● Like 기능 구현
1. like api Controller 구현
@RestController
@RequestMapping("/app/users")
public class PostController {
private final UserService userService;
private final PostService postService;
private final S3Service s3Service;
private final JwtService jwtService;
private final LikeService likeService;
@Autowired
public PostController(UserService userService,
PostService postService, S3Service s3Service,
JwtService jwtService, LikeService likeService) {
this.userService = userService;
this.postService = postService;
this.s3Service = s3Service;
this.jwtService = jwtService;
this.likeService = likeService;
}
...
@PostMapping("/like/{postId}")
public BaseResponse<?> likes(@PathVariable long postId){
try{
// 주소의 유저번호가 없으면 에러
if (!postService.checkPostExist(postId)){
return new BaseResponse<>(POST_ID_NOT_EXISTS);
}
Long loginUserId = jwtService.getUserIdx();
// 게시물 작성자와 좋아요 유저가 같으면 에러
if (postService.getPostWriter(postId)==loginUserId) {
return new BaseResponse<>(POST_CANNOT_MYSELF);
}
likeService.Like(postId,loginUserId);
} catch (BaseException exception) {
return new BaseResponse<>((exception.getStatus()));
}
return new BaseResponse<>("좋아요 요청에 성공했습니다.");
}
@PostMapping("/unlike/{postId}")
public BaseResponse<?> unlikes(@PathVariable long postId){
try{
// 주소의 유저번호가 없으면 에러
if (!postService.checkPostExist(postId)){
return new BaseResponse<>(POST_ID_NOT_EXISTS);
}
Long loginUserId = jwtService.getUserIdx();
likeService.unLike(postId,loginUserId);
} catch (BaseException exception) {
return new BaseResponse<>((exception.getStatus()));
}
return new BaseResponse<>("좋아요 취소 요청에 성공했습니다.");
}
}
2. LikeService 구현
@RequiredArgsConstructor
@Service
public class LikeService {
private final LikeRepository likeRepository;
@Transactional
public void Like(long postId,long loginUserId) {likeRepository.postLike(postId,loginUserId);}
@Transactional
public void unLike(long postId,long loginUserId) {likeRepository.postUnLike(postId,loginUserId);}
@Transactional
public long countPostLikes(long postId){
return likeRepository.countBypostId(postId);
}
}
3. LikeRepo 구현
// LikeRepository.java
public interface LikeRepository extends JpaRepository<PostLike,Long> {
@Modifying
@Query(value="INSERT INTO postLike(postId,userId,updatedAt,createdAt,status)
VALUES(:postId,:loginUserId,now(),now(),'ACTIVE')",nativeQuery = true)
int postLike(long postId,long loginUserId);
@Modifying
@Query(value = "DELETE FROM postLike WHERE postId = :postId AND userId= :loginUserId",
nativeQuery = true)
int postUnLike(long postId,long loginUserId);
Long countBypostId(long postId);
}