TIL/Project

TIL 2024-11-21 (todo-log 3일차)

myoma 2024. 11. 21. 22:30

1 ) 프로젝트 진행정도

  • 피드(feed) CRUD
    • 피드 생성
    • 피드 조회
      • 단건 조회
      • 전체 조회
    • 피드 수정
    • 피드 삭제 (2일차 완료)
  • 친구 관리 기능
    • 팔로우 기능
    • 팔로워 목록 조회
    • 팔로잉 목록 조회
    • 언팔로우
    • 팔로잉의 게시글 조회
      • 생성순
  • 업그레이드 뉴스피드 기능
    • 전체 피드 수정순으로 조회 (3일차 완료)
    • 좋아요 순으로 조회
    • 날짜별 기간 검색 기능

 


  • Repository, Entity 생략.

 

  • 팔로우 기능 구현
    • 팔로우하기
    • Controller
@PostMapping("/{followerNickname}/{followingNickname}")

    public ResponseEntity<String> followUser(
    @PathVariable String followerNickname, 
    @PathVariable String followingNickname) {
    
        followService.followUser(followerNickname, followingNickname);
        return ResponseEntity.ok("팔로우 신청 완료!");
        
    }
  • 반환타입을 Srtring으로 하여 팔로우 신청이 완료된 것을 반환.
  • @PathVariable을 사용해서 팔로워와 팔로잉을 받아 url로 처리한다.
  • 2개의 닉네임을 받아 follow service에서 처리.
    • Service
 public void followUser(String followerNickname, String followingNickname) {

        User follower = userRepository.findByNickname(followerNickname).orElseThrow(
                () -> new IllegalArgumentException("팔로워를 찾을 수 없습니다."));
        User following = userRepository.findByNickname(followingNickname).orElseThrow(
                () -> new IllegalArgumentException("팔로잉을 찾을 수 없습니다."));

        // 자기 자신을 팔로우하지 못하게 설정
        if(Objects.equals(followerNickname, followingNickname)) {
            throw new CustomException(ErrorCode.DUPLICATE_RESOURCE);
        }

        // 이미 팔로우 일 때
        if(followRepository.findByFollowerAndFollowing(follower, following).isPresent()) {
            throw new CustomException(ErrorCode.DUPLICATE_RESOURCE);
        }

        Follow follow = new Follow();
        follow.setFollower(follower);
        follow.setFollowing(following);

        followRepository.save(follow);
    }
  • 미리 만들어진 User 타입의 객체를 만들어 그 곳에 userRepository에서 닉네임으로 팔로워가 존재하는지 확인.
  • 팔로잉도 위와 같은 방법으로 존재확인.
  • 두 개의 닉네임이 검증이 완료되었다면 두 개의 닉네임이 같은지 확인하여 자기 자신을 팔로우 하지 못하게 조건을 건다.
  • 새로운 follow 인스턴스를 생성하여 그곳에 미리 만들어둔 Setter 팔로워, 팔로잉을 follow 객체에 저장하여 follow Repository에 저장한다.

 

 

  • 사용자의 팔로잉 목록 조회
  • Controller
    // 사용자의 팔로잉 목록 조회
    @GetMapping("/following/{nickname}")
    public ResponseEntity<List<FollowDto>> findFollowing(@PathVariable String nickname) {
        return ResponseEntity.ok(followService.findFollowing(nickname));
    }
  • 이번에도 역시 url을 이용하기 위해 @PathVariable를 사용한다.
  • 서비스 로직에 findFollowing 이라는 메서드를 만들어 닉네임을 넣어준다.

 

  • Service
 public List<FollowDto> findFollowing(String nickname) {
        User user = userRepository.findByNickname(nickname).orElseThrow(
                () -> new IllegalArgumentException("User not found"));

        return followRepository.findByFollower(user).stream()
                .map(follow -> new FollowDto(
                        follow.getFollowing().getNickname(),
                        follow.getFollowing().getEmail(),
                        follow.getFollowing().getMbti(),
                        follow.getFollowing().getStatusMs()
                )).collect(Collectors.toList());
    }
  • 서비스 로직에서 메서드를 만들 때 컨트롤러에서 미리 작성하면 problem이 발생하는데 이것을 클릭하면 자동 뼈대 생성.
  • 여기서 일단 맨 처음에 User에 우리가 작성한 nickname이 있으면 user 객체에 넣어주고 없으면 예외처리로 반환.
  • stream()은 stream이라는 타입으로 변환시키는 것이고 그것을 map() 하나씩 가져와 stream 타입으로 넣어주는 것이다.
  • 마지막으로 toList는 다시 List 타입으로 반환한다.

 

 

  • 언팔로우 ( 팔로우 취소하기)
  • Controller
    //팔로우 해제 (언팔로우)
    @DeleteMapping("/{followerNickname}/{followingNickname}")
    public ResponseEntity<String> unfollowUser(
            @PathVariable String followerNickname,
            @PathVariable String followingNickname) {
        followService.unfollowUser(followerNickname, followingNickname);
        return ResponseEntity.ok("팔로우 삭제 완료!");
    }
  • @PathVariable은 이미 두 번 설명했기에 생략.
  • 이번에도 Service 로직에 새로운 메서드를 만들어서 구현

 

  • Service
public void unfollowUser(String followerNickname, String followingNickname) {

        // 팔로워 사용자 조회
        User follower = userRepository.findByNickname(followerNickname).orElseThrow(
                () -> new IllegalArgumentException("팔로우를 찾을 수 없습니다."));

        // 팔로잉 사용자 조회
        User following = userRepository.findByNickname(followingNickname).orElseThrow(
                () -> new IllegalArgumentException("팔로잉을 찾을 수 없습니다."));

        // 스스로 삭제시 에러 발생
        if(Objects.equals(followerNickname, followingNickname)) {
            throw new CustomException(ErrorCode.DUPLICATE_RESOURCE);
        }

        // 객체 조회
        Follow follow = followRepository.findByFollowerAndFollowing(follower, following)
                .orElseThrow(() -> new IllegalArgumentException("Follow relationship not found"));

        followRepository.delete(follow);
    }
  • 처음에 팔로워 사용자가 존재하는지 조회
  • 팔로잉 사용자 또한 존재하는 조회
  • 여기서 이때 자기 자신을 삭제할 순 없으니 두 닉네임을 비교하여 같으면 에러 발생
  • 모든 조건이 충족하면 객체를 조회하여 객체가 존재하면 follow에 넣어주고 그 follow를 delete를 이용해 삭제.

 

 

  • 사용자 팔로잉 최신 게시물 조회
  • Controller
    // 사용자의 팔로잉 게시글 조회
    @GetMapping("/{nickname}/followingFeeds")
    public List<FeedResponseDto> findFollowingFeeds(@PathVariable String nickname) {
        return followService.findFollowingFeeds(nickname);
    }
  • 팔로잉 게시글을 조회할 때 조건이 있는데 바로 팔로잉의 게시물을 최신순으로 나열.

 

  • Service
    // 사용자 팔로워 최신 게시물 조회
    public List<FeedResponseDto> findFollowingFeeds(String nickname) {
        User user = userRepository.findByNickname(nickname).orElseThrow(
                () -> new CustomException(ErrorCode.DUPLICATE_RESOURCE));

        List<User> followingUsers = followRepository.findByFollower(user)
                .stream()
                .map(Follow::getFollowing)
                .collect(Collectors.toList());

        List<Feed> feeds = feedRepository.findByUserInOrderByCreatedAtDesc(followingUsers);

        return feeds.stream()
                .map(FeedResponseDto::feedDto)
                .collect(Collectors.toList());
    }
  • findByNickname으로 사용자를 조회한다.
  • List 객체를 만들어 팔로잉들의 모든 데이터를 저장하고 feed List 객체를 생성하여 그곳에서 생성 날짜 순으로 정렬.
  • 리턴할 때 feeds에서 원하는 데이터만 가져올 수 있도록 FeedResponseDto에서 미리 만든 Set 데이터를 이용하여 반환.

'TIL > Project' 카테고리의 다른 글

TIL 2024-11-28 (Trouble Shooting (통화 환율) )  (2) 2024.11.28
[KPT 회고록] (project : todo-log)  (0) 2024.11.25
TIL 2024-11-20 (todo-log 2일차)  (0) 2024.11.20
TIL 2024-11-19 (todo-log)  (1) 2024.11.19
Trouble Shooting ( Calender_JPA)  (0) 2024.11.15