-
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
[LIME-9] 친구 관계 기능 추가 #15
Merged
Merged
Changes from 19 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
e761c40
feat: 팔로우 기능 추가
Yiseull bcf1627
feat: 언팔로우 기능 추가
Yiseull a321c86
fix: 팔로워, 팔로잉 거꾸로 저장되는 버그 수정
Yiseull 870b237
feat: 팔로워 목록 조회 기능 추가
Yiseull 9f2325d
refactor: 팔로워 목록 dto명 변경
Yiseull 0163567
refactor: 팔로워 목록 조회 메서드명 변경
Yiseull 77eb08b
feat: 팔로잉 목록 조회 기능 추가
Yiseull 4241aae
refactor: 팔로우 목록 조회랑 팔로워 목록 조회의 공통 로직을 메서드로 추출
Yiseull e5892ee
fix: 소셜로그인 추가로 인한 변경
Yiseull 7669afd
feat: 마이페이지 조회에 팔로워 수, 팔로잉 수 추가
Yiseull 8fd822b
fix: 팔로우 할 때 이미 친구인 경우 계속 친구 관계가 추가되는 버그 수정
Yiseull d01ac33
feat: Friendship에서 toMember, fromMember 객체참조로 변경
Yiseull 0b6013e
test: 팔로우 테스트 추가
Yiseull 1ff2a14
fix: rebase main 할 때 생긴 오류 해결
Yiseull e8342e2
test: 팔로워 수 조회 테스트, 팔로잉 수 조회 테스트 추가
Yiseull 55c0c55
test: 언팔로우 테스트 추가
Yiseull 0e734f5
rename: FriendshipBuilder 패키지 이동
Yiseull dc0ef95
test: 팔로워 조회, 팔로잉 조회, 친구 관계 조회 테스트 추가
Yiseull b050686
refactor: stream().forEach() -> forEach()
Yiseull 6197520
comment: 팔로워, 팔로잉 목록 조회 설명 변경
Yiseull File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
75 changes: 75 additions & 0 deletions
75
...-api/src/main/java/com/programmers/lime/domains/friendships/api/FriendshipController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package com.programmers.lime.domains.friendships.api; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.ModelAttribute; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import com.programmers.lime.common.cursor.CursorSummary; | ||
import com.programmers.lime.domains.friendships.api.dto.response.FriendshipGetByCursorResponse; | ||
import com.programmers.lime.domains.friendships.application.FriendshipService; | ||
import com.programmers.lime.domains.friendships.model.FriendshipSummary; | ||
import com.programmers.lime.global.cursor.CursorRequest; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Tag(name = "friendships", description = "친구 관계 API") | ||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/api/friendships") | ||
public class FriendshipController { | ||
|
||
private final FriendshipService friendshipService; | ||
|
||
@Operation(summary = "팔로우", description = "팔로우 할 닉네임을 이용하여 팔로우 합니다.") | ||
@PostMapping("/follow/{nickname}") | ||
public ResponseEntity<Void> follow(@PathVariable final String nickname) { | ||
friendshipService.follow(nickname); | ||
|
||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@Operation(summary = "언팔로우", description = "언팔로우 할 닉네임을 이용하여 팔로우를 취소합니다.") | ||
@PostMapping("/unfollow/{nickname}") | ||
public ResponseEntity<Void> unfollow(@PathVariable final String nickname) { | ||
friendshipService.unfollow(nickname); | ||
|
||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@Operation(summary = "팔로워 목록 조회", description = "회원을 팔로우한 사람들의 목록을 조회한다.") | ||
@GetMapping("/follower/{nickname}") | ||
public ResponseEntity<FriendshipGetByCursorResponse> getFollower( | ||
@PathVariable final String nickname, | ||
@ModelAttribute @Valid final CursorRequest request | ||
) { | ||
final CursorSummary<FriendshipSummary> cursorSummary = friendshipService.getFollower( | ||
nickname, | ||
request.toParameters() | ||
); | ||
final FriendshipGetByCursorResponse response = FriendshipGetByCursorResponse.from(cursorSummary); | ||
|
||
return ResponseEntity.ok(response); | ||
} | ||
|
||
@Operation(summary = "팔로잉 목록 조회", description = "회원이 팔로우한 사람들의 목록을 조회한다.") | ||
@GetMapping("/following/{nickname}") | ||
public ResponseEntity<FriendshipGetByCursorResponse> getFollowing( | ||
@PathVariable final String nickname, | ||
@ModelAttribute @Valid final CursorRequest request | ||
) { | ||
final CursorSummary<FriendshipSummary> cursorSummary = friendshipService.getFollowing( | ||
nickname, | ||
request.toParameters() | ||
); | ||
final FriendshipGetByCursorResponse response = FriendshipGetByCursorResponse.from(cursorSummary); | ||
|
||
return ResponseEntity.ok(response); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
.../programmers/lime/domains/friendships/api/dto/response/FriendshipGetByCursorResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.programmers.lime.domains.friendships.api.dto.response; | ||
|
||
import java.util.List; | ||
|
||
import com.programmers.lime.common.cursor.CursorSummary; | ||
import com.programmers.lime.domains.friendships.model.FriendshipSummary; | ||
|
||
public record FriendshipGetByCursorResponse( | ||
String nextCursorId, | ||
Integer totalCount, | ||
List<FriendshipSummary> followers | ||
) { | ||
public static FriendshipGetByCursorResponse from(final CursorSummary<FriendshipSummary> cursorSummary) { | ||
return new FriendshipGetByCursorResponse( | ||
cursorSummary.nextCursorId(), | ||
cursorSummary.summaryCount(), | ||
cursorSummary.summaries() | ||
); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
...src/main/java/com/programmers/lime/domains/friendships/application/FriendshipService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.programmers.lime.domains.friendships.application; | ||
|
||
import org.springframework.stereotype.Service; | ||
|
||
import com.programmers.lime.common.cursor.CursorPageParameters; | ||
import com.programmers.lime.common.cursor.CursorSummary; | ||
import com.programmers.lime.domains.friendships.implementation.FriendshipAppender; | ||
import com.programmers.lime.domains.friendships.implementation.FriendshipReader; | ||
import com.programmers.lime.domains.friendships.implementation.FriendshipRemover; | ||
import com.programmers.lime.domains.friendships.model.FriendshipSummary; | ||
import com.programmers.lime.domains.member.domain.Member; | ||
import com.programmers.lime.domains.member.implementation.MemberReader; | ||
import com.programmers.lime.global.util.MemberUtils; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class FriendshipService { | ||
|
||
private final FriendshipAppender friendshipAppender; | ||
private final FriendshipRemover friendshipRemover; | ||
private final FriendshipReader friendshipReader; | ||
private final MemberUtils memberUtils; | ||
private final MemberReader memberReader; | ||
|
||
public void follow(final String nickname) { | ||
final Member fromMember = memberUtils.getCurrentMember(); | ||
final Member toMember = memberReader.readByNickname(nickname); | ||
|
||
friendshipAppender.append(toMember, fromMember); | ||
} | ||
|
||
public void unfollow(final String nickname) { | ||
final Member fromMember = memberUtils.getCurrentMember(); | ||
final Member toMember = memberReader.readByNickname(nickname); | ||
|
||
friendshipRemover.remove(toMember, fromMember); | ||
} | ||
|
||
public CursorSummary<FriendshipSummary> getFollower( | ||
final String nickname, | ||
final CursorPageParameters parameters | ||
) { | ||
return friendshipReader.readFollowerByCursor(nickname, parameters); | ||
} | ||
|
||
public CursorSummary<FriendshipSummary> getFollowing( | ||
final String nickname, | ||
final CursorPageParameters parameters | ||
) { | ||
return friendshipReader.readFollowingByCursor(nickname, parameters); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
lime-domain/src/main/java/com/programmers/lime/domains/friendships/domain/Friendship.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package com.programmers.lime.domains.friendships.domain; | ||
|
||
import java.util.Objects; | ||
|
||
import com.programmers.lime.domains.BaseEntity; | ||
import com.programmers.lime.domains.member.domain.Member; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import jakarta.persistence.Table; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@Entity | ||
@Table(name = "friendships") | ||
public class Friendship extends BaseEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "to_member_id", nullable = false) | ||
private Member toMember; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "from_member_id", nullable = false) | ||
private Member fromMember; | ||
Comment on lines
+32
to
+38
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. 궁금한게 manyToOne으로 연관관계를 맺어줬을 때 발생하는 트러블 슈팅은 없었나요? 맞팔로잉 상태면 순환 관련 문제가 있을 수 있지 않을까 예상했는데 단방향이라 없을 것 같기도 하네요 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. 단방향이여서 순환참조 문제는 없을 것 같아요!! 생기면 바로 공유하겠습니다😎 |
||
|
||
public Friendship( | ||
final Member toMember, | ||
final Member fromMember | ||
) { | ||
this.toMember = Objects.requireNonNull(toMember); | ||
this.fromMember = Objects.requireNonNull(fromMember); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...main/java/com/programmers/lime/domains/friendships/implementation/FriendshipAppender.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.programmers.lime.domains.friendships.implementation; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
import com.programmers.lime.domains.friendships.domain.Friendship; | ||
import com.programmers.lime.domains.friendships.repository.FriendshipRepository; | ||
import com.programmers.lime.domains.member.domain.Member; | ||
import com.programmers.lime.error.BusinessException; | ||
import com.programmers.lime.error.ErrorCode; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class FriendshipAppender { | ||
|
||
private final FriendshipRepository friendshipRepository; | ||
|
||
public Friendship append( | ||
final Member toMember, | ||
final Member fromMember | ||
) { | ||
if (friendshipRepository.existsByToMemberAndFromMember(toMember, fromMember)) { | ||
throw new BusinessException(ErrorCode.FRIENDSHIP_ALREADY_EXISTS); | ||
} | ||
|
||
final Friendship friendship = new Friendship(toMember, fromMember); | ||
|
||
return friendshipRepository.save(friendship); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
.../main/java/com/programmers/lime/domains/friendships/implementation/FriendshipCounter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.programmers.lime.domains.friendships.implementation; | ||
|
||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import com.programmers.lime.domains.friendships.repository.FriendshipRepository; | ||
import com.programmers.lime.domains.member.domain.Member; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class FriendshipCounter { | ||
|
||
private final FriendshipRepository friendshipRepository; | ||
|
||
@Transactional(readOnly = true) | ||
public long countFollower(final Member member) { | ||
return friendshipRepository.countByToMember(member); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public long countFollowing(final Member member) { | ||
return friendshipRepository.countByFromMember(member); | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
...c/main/java/com/programmers/lime/domains/friendships/implementation/FriendshipReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.programmers.lime.domains.friendships.implementation; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import com.programmers.lime.common.cursor.CursorPageParameters; | ||
import com.programmers.lime.common.cursor.CursorSummary; | ||
import com.programmers.lime.common.cursor.CursorUtils; | ||
import com.programmers.lime.domains.friendships.domain.Friendship; | ||
import com.programmers.lime.domains.friendships.model.FriendshipSummary; | ||
import com.programmers.lime.domains.friendships.repository.FriendshipRepository; | ||
import com.programmers.lime.domains.member.domain.Member; | ||
import com.programmers.lime.error.EntityNotFoundException; | ||
import com.programmers.lime.error.ErrorCode; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class FriendshipReader { | ||
|
||
public static final int DEFAULT_PAGING_SIZE = 20; | ||
|
||
private final FriendshipRepository friendshipRepository; | ||
|
||
@Transactional(readOnly = true) | ||
public Friendship read( | ||
final Member toMember, | ||
final Member fromMember | ||
) { | ||
return friendshipRepository.findByToMemberAndFromMember(toMember, fromMember) | ||
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.FRIENDSHIP_NOT_FOUND)); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public CursorSummary<FriendshipSummary> readFollowerByCursor( | ||
final String nickname, | ||
final CursorPageParameters parameters | ||
) { | ||
final int pageSize = getPageSize(parameters); | ||
final List<FriendshipSummary> followerSummaries = friendshipRepository.findFollowerByCursor( | ||
nickname, | ||
parameters.cursorId(), | ||
pageSize | ||
); | ||
|
||
return CursorUtils.getCursorSummaries(followerSummaries); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public CursorSummary<FriendshipSummary> readFollowingByCursor( | ||
final String nickname, | ||
final CursorPageParameters parameters | ||
) { | ||
final int pageSize = getPageSize(parameters); | ||
final List<FriendshipSummary> followerSummaries = friendshipRepository.findFollowingByCursor( | ||
nickname, | ||
parameters.cursorId(), | ||
pageSize | ||
); | ||
|
||
return CursorUtils.getCursorSummaries(followerSummaries); | ||
} | ||
|
||
private int getPageSize(final CursorPageParameters parameters) { | ||
return parameters.size() == null ? DEFAULT_PAGING_SIZE : parameters.size(); | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
.../main/java/com/programmers/lime/domains/friendships/implementation/FriendshipRemover.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.programmers.lime.domains.friendships.implementation; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
import com.programmers.lime.domains.friendships.domain.Friendship; | ||
import com.programmers.lime.domains.friendships.repository.FriendshipRepository; | ||
import com.programmers.lime.domains.member.domain.Member; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class FriendshipRemover { | ||
|
||
private final FriendshipRepository friendshipRepository; | ||
private final FriendshipReader friendshipReader; | ||
|
||
public void remove( | ||
final Member toMember, | ||
final Member fromMember | ||
) { | ||
final Friendship friendship = friendshipReader.read(toMember, fromMember); | ||
friendshipRepository.delete(friendship); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
설명 팔로잉으로 고치면 될거같아욤
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.
6197520
설명 수정했습니다! 😄