3가지 기능을 구현해준다.
1. 유저 목록을 알맞게 반환해주는 기능
2. 유저가 following한 정보를 저장해주는 기능
3. 유저가 following 했던 정보를 삭제해주는 기능
1. UserDto, UserListResponseDto 작성
@Data
public class UserDto {
private String email;
private String nickname;
private String profileUrl;
private boolean isFollow;
@Builder
public UserDto(String email, String nickname, String profileUrl, boolean isFollow) {
this.email = email;
this.nickname = nickname;
this.profileUrl = profileUrl;
this.isFollow = isFollow;
}
}
@Data
public class UserListResponseDto {
private List<UserDto> userList;
@Builder
public UserListResponseDto(List<UserDto> userList) {
this.userList = userList;
}
}
- UserListResponseDto는 UserDto 목록을 리스트 형식으로 반환한다.
- UserDto는 유저의 email, nickname, profileUrl, 팔로우 상태를 반환한다.
2. FollowRepository 수정
public interface FollowRepository extends JpaRepository<Follow, Long> {
boolean existsByFollowerAndFollowing(User follower, User following);
Optional<Follow> findByFollowerAndFollowing(User follower, User following);
}
- 해당 유저를 팔로잉하고 있는지에 대한 결과를 bool로 반환해주는 exists 메서드와, find 메서드를 작성해준다.
3. FollowService 작성
@Service
@Slf4j
@RequiredArgsConstructor
public class FollowService {
private final UserRepository userRepository;
private final FollowRepository followRepository;
@Transactional
public UserListResponseDto getUserList(User user) {
// DB에서 조회한 모든 유저 리스트
List<User> userList = userRepository.findAll();
// UserDto로 변환할 리스트
List<UserDto> userDtoList = new ArrayList<>();
// 유저리스트 중 본인을 뺀 나머지 유저들을 UserDto 형식에 맞게 변경
userList.forEach((u) -> {
if(!u.getEmail().equals(user.getEmail())) {
userDtoList.add(UserDto.builder()
.email(u.getEmail())
.profileUrl(u.getProfileImgUrl())
.nickname(u.getNickname())
.isFollow(followRepository.existsByFollowerAndFollowing(user, u))
.build());
}
});
return UserListResponseDto.builder().userList(userDtoList).build();
}
@Transactional
public UserListResponseDto saveFollow(User user, String email) {
// 팔로잉하는 유저 검색
User following = userRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException("유저 정보를 찾을 수 없습니다."));
// 팔로잉 유저에 대한 팔로잉 정보 저장
followRepository.save(Follow.builder()
.following(following)
.follower(user)
.build());
return this.getUserList(user);
}
@Transactional
public UserListResponseDto deleteFollow(User user, String email) throws Exception {
// 팔로잉하는 유저와 팔로잉 정보 검색
User following = userRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException("유저 정보를 찾을 수 없습니다."));
Follow follow = followRepository.findByFollowerAndFollowing(user, following).orElseThrow(() -> new Exception("팔로우 처리 중 에러가 발생하였습니다"));
// 팔로잉 정보 삭제
followRepository.delete(follow);
return this.getUserList(user);
}
}
- getUserList는 모든 유저리스트를 가져와 본인을 제외한 정보를 UserDto형식으로 변환하여 반환한다.
- saveFollow는 팔로잉 정보를 저장 후, getUserList 결과를 반환한다.
- deleteFollow는 팔로잉 정보를 삭제 후, getUserList 결과를 반환한다.
4. FollowController 작성
@RestController
@Slf4j
@RequiredArgsConstructor
public class FollowController {
private final FollowService followService;
@GetMapping("/user-list")
public ResponseEntity getUserList(@CurrentUser User user) {
try {
return ResponseEntity.ok().body(followService.getUserList(user));
} catch (Exception e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
@GetMapping("/follow")
public ResponseEntity follow(@CurrentUser User user, @RequestParam(value = "followingEmail") String followingEmail) {
try {
return ResponseEntity.ok().body(followService.saveFollow(user, followingEmail));
} catch (Exception e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
@DeleteMapping("/follow")
public ResponseEntity unFollow(@CurrentUser User user, @RequestParam(value = "followingEmail") String followingEmail) {
try {
return ResponseEntity.ok().body(followService.deleteFollow(user, followingEmail));
} catch (Exception e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
}
- 유저 정보 조회는 '/api/user-list' URL로 GET으로 요청받아 처리한다.
- 팔로우, 언팔로우 기능은 각각 Get, Delete 메서드로 요청받고 팔로잉 유저 정보는 파라미터 followingEmail 로 받아 처리한다.
5. 동작 모습
'Web > 인스타 클론 코딩' 카테고리의 다른 글
[인스타그램 클론코딩] 08. 홈 화면 구현(Front-End) (0) | 2023.02.03 |
---|---|
[인스타그램 클론코딩] 08. 홈 화면 구현(Back-End) (0) | 2023.02.03 |
[인스타그램 클론코딩] 07. 팔로우 기능 구현(Front-End) (0) | 2023.02.02 |
[인스타그램 클론코딩] 06. 게시글 Posting 구현(Back-End) (0) | 2023.02.02 |
[인스타그램 클론코딩] 06. 게시글 Posting 구현(Front-End) (0) | 2023.02.02 |