팔로우 및 팔로우 취소 기능을 추가하는 것은 소셜 네트워킹 기능의 핵심적인 부분입니다. 이 기능을 통해 사용자들은 다른 사용자를 팔로우할 수 있으며, 원할 때 팔로우를 취소할 수도 있습니다.
FollowController 구현
FollowController는 팔로우와 팔로우 취소 요청을 처리합니다. 사용자 ID는 토큰 컨텍스트에서 추출합니다.
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class FollowController {
private final FollowService followService;
@PostMapping("/follow/{followingId}")
public ResponseEntity<?> follow(@PathVariable Long followingId) {
TokenContext context = TokenContextHolder.getContext();
Long followerId = context.getUserId();
followService.follow(followerId, followingId);
return ResponseEntity.ok().build();
}
@DeleteMapping("/unfollow/{followingId}")
public ResponseEntity<?> unfollow(@PathVariable Long followingId) {
TokenContext context = TokenContextHolder.getContext();
Long followerId = context.getUserId();
followService.unfollow(followerId, followingId);
return ResponseEntity.ok().build();
}
}
Follow 엔티티 정의
Follow 엔티티는 팔로우 관계를 나타냅니다. follower와 following 필드는 각각 팔로워와 팔로잉하는 사용자를 참조합니다.
@Entity
@Table(name = "follows")
@NoArgsConstructor
@Getter
public class Follow extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "follower_id")
private User follower;
@ManyToOne
@JoinColumn(name = "following_id")
private User following;
public void setFollower(User follower) {
this.follower = follower;
follower.getFollowings().add(this);
}
public void setFollowing(User following) {
this.following = following;
following.getFollowers().add(this);
}
User 연관관계 매핑
연관관계 매핑을 통해 팔로우와 유저 도메인을 연결합니다.
@OneToMany(mappedBy = "follower")
private List<Follow> followers = new ArrayList<>();
@OneToMany(mappedBy = "following")
private List<Follow> followings = new ArrayList<>();
FollowRepository 인터페이스
FollowRepository는 팔로우 관계를 관리하기 위한 JPA 리포지토리입니다.
public interface FollowRepository extends JpaRepository<Follow, Long> {
Optional<Follow> findByFollowerAndFollowing(User follower, User following);
}
FollowService 구현
FollowService에서는 실제로 팔로우와 팔로우 취소 기능의 비즈니스 로직을 처리합니다.
@Service
@RequiredArgsConstructor
public class FollowService {
private final UserRepository userRepository;
private final FollowRepository followRepository;
@Transactional
public void follow(Long followerId, Long followingId) {
if (followerId.equals(followingId)) {
throw new BadRequestException("사용자는 자신을 팔로우할 수 없습니다.");
}
User follower = userRepository.findById(followerId).orElseThrow(
() -> new BadRequestException("팔로워 사용자를 찾을 수 없습니다.")
);
User following = userRepository.findById(followingId).orElseThrow(
() -> new BadRequestException("팔로잉 사용자를 찾을 수 없습니다.")
);
if (followRepository.findByFollowerAndFollowing(follower, following).isPresent()) {
throw new BadRequestException("이미 팔로우한 유저입니다.");
}
Follow follow = new Follow();
follow.setFollower(follower);
follow.setFollowing(following);
followRepository.save(follow);
}
@Transactional
public void unfollow(Long followerId, Long followingId) {
User follower = userRepository.findById(followerId).orElseThrow(
() -> new BadRequestException("팔로워 사용자를 찾을 수 없습니다.")
);
User following = userRepository.findById(followingId).orElseThrow(
() -> new BadRequestException("팔로잉 사용자를 찾을 수 없습니다.")
);
if (!followRepository.findByFollowerAndFollowing(follower, following).isPresent()) {
throw new BadRequestException("없는 유저입니다.");
}
followRepository.findByFollowerAndFollowing(follower, following)
.ifPresent(followRepository::delete);
}
}
WebSecurityConfig 수정
WebSecurityConfig에서는 팔로우 및 팔로우 취소 요청 경로에 대해 보안 설정을 조정합니다.
.antMatchers(HttpMethod.DELETE, "/api/**").permitAll()
결론
팔로우 및 팔로우 취소 기능을 통해 사용자들은 서로의 활동을 구독하고, 관심 있는 콘텐츠를 쉽게 찾을 수 있습니다. 이 기능은 사용자 간의 상호 작용을 증가시키며, 커뮤니티의 활성화에 기여합니다. 위의 구현 예시를 통해 기본적인 팔로우 시스템을 프로젝트에 통합할 수 있습니다.
'프로젝트 (Java) > 예약마켓' 카테고리의 다른 글
[프로젝트] 16. 게시물 전체 조회 및 ID로 상세 정보 조회 (0) | 2024.01.26 |
---|---|
[프로젝트] 15. 게시물 관련 DTO 설계 및 게시물 추가 API 구현 (0) | 2024.01.26 |
[프로젝트] 13. BaseTimeEntity 추가를 통한 데이터 생명 주기 관리 (0) | 2024.01.26 |
[프로젝트] 12. 비밀번호 업데이트 기능 (0) | 2024.01.26 |
[프로젝트] 11. 프로필 전체 조회 및 ID를 통한 개별 사용자 조회 기능 (0) | 2024.01.26 |