Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
Tags
- 격파르타장점
- java기본자료형
- javaJRE
- java list 저장
- 노베이스부트캠프
- 항해15기
- java참조자료형
- java최솟값구하기
- sqld자격증합격
- java map
- 컴파일
- 격파르타후기
- 비전공자sqld
- java map 저장
- java list 출력
- java 자료구조 활용
- java알고리즘문제풀이
- javaJVM
- 격파르타비전공자
- 항해99후기
- java알고리즘
- java map 출력
- java set 저장
- 격파르타합격후기
- 인터프린터언어
- 코딩부트캠프후기
- 프로그래머스제일작은수
- 프로그래머스
- 작은수제거하기
- java set 출력
Archives
- Today
- Total
코딩과 결혼합니다
230902 - (코드리팩토링) api 6개를 3개로 합치기!! 본문
728x90
기존 TagController코드 -> 수정 후 코드
TagController
@RestController
@RequiredArgsConstructor
@RequestMapping("/tags")
public class TagController {
private final TagService tagService;
//전체 태그 인기순위
@GetMapping("/All")
public List<String> allRankNumber(){
return tagService.allRankNumber();
}
//카테고리별 태그 인기순위
@GetMapping("/category")
public List<String> categoryRankNumer(@RequestParam String category){
return tagService.categoryRankNumer(category);
}
//전체 인기 순위 태그 post 조회
@GetMapping("/post/All")
public PostListResponse hashtagPostResponseDtos(
@RequestParam int size,
@RequestParam int page,
@RequestParam String hashtagName,
@RequestParam String type,
@AuthenticationPrincipal UserDetailsImpl userDetails
){
if(Objects.isNull(userDetails)){
return tagService.hashtagPostResponseDtos(size, page-1, hashtagName, type, null);
}
User user = userDetails.getUser();
return tagService.hashtagPostResponseDtos(size, page-1, hashtagName, type, user);
}
//전체 인기 순위 태그 post 조회 - 위치
@GetMapping("/post/location/All")
public PostListResponse postLocationResponseDtos(
@RequestParam int size,
@RequestParam int page,
@RequestParam String gu,
@AuthenticationPrincipal UserDetailsImpl userDetails
){
if(Objects.isNull(userDetails)){
return tagService.postLocationResponseDtos(size, page-1, gu, null);
}
User user = userDetails.getUser();
return tagService.postLocationResponseDtos(size, page-1,gu, user);
}
//카테고리별 인기 순위 태그 post 조회
@GetMapping("/post/category")
public PostListResponse categoryHashtagPostResponseDtos(
@RequestParam int size,
@RequestParam int page,
@RequestParam String hashtagName,
@RequestParam String category,
@RequestParam String type,
@AuthenticationPrincipal UserDetailsImpl userDetails
){
if(Objects.isNull(userDetails)){
return tagService.categoryHashtagPostResponseDtos(size, page-1, hashtagName, category , type, null);
}
User user = userDetails.getUser();
return tagService.categoryHashtagPostResponseDtos(size, page-1, hashtagName, category,type,user);
}
//카테고리별 인기 순위 태그 post 조회 + 위치
@GetMapping("/post/location/category")
public PostListResponse categoryLocationPostResponseDtos(
@RequestParam int size,
@RequestParam int page,
@RequestParam String gu,
@RequestParam String category,
@AuthenticationPrincipal UserDetailsImpl userDetails
){
if(Objects.isNull(userDetails)){
return tagService.categoryLocationPostResponseDtos(size, page-1, gu, category , null);
}
User user = userDetails.getUser();
return tagService.categoryLocationPostResponseDtos(size, page-1, gu, category, user);
}
}
수정 TagController
@RestController
@RequiredArgsConstructor
@RequestMapping("/tags")
public class TagController {
private final TagService tagService;
//태그 인기순위
@GetMapping("/rank")
public List<String> rankNumber(@RequestParam String category){
return tagService.rankNumber(category);
}
//태그별 포스트
@GetMapping("/posts")
public PostListResponse tagsPosts(
@RequestParam int size,
@RequestParam int page,
@RequestParam String hashtagName,
@RequestParam String type,
@RequestParam String category,
@AuthenticationPrincipal UserDetailsImpl userDetails
){
if(Objects.isNull(userDetails)){
return tagService.tagsPosts(size, page-1, hashtagName, type, category, null);
}
User user = userDetails.getUser();
return tagService.tagsPosts(size, page-1, hashtagName, type,category, user);
}
//태그별 post + 위치
@GetMapping("/posts/location")
public PostListResponse postLocation(
@RequestParam int size,
@RequestParam int page,
@RequestParam String gu,
@RequestParam String category,
@AuthenticationPrincipal UserDetailsImpl userDetails
){
if(Objects.isNull(userDetails)){
return tagService.postLocation(size, page-1, gu, category, null);
}
User user = userDetails.getUser();
return tagService.postLocation(size, page-1,gu, category, user);
}
}
기존의 코드는 회원일 때 보이는 api와 비회원일 때 보이는 api 이렇게 각각 2개씩 있었는데,
유저의 정보(토큰)가 null 인지 아닌지에 따라서 return 하는 값을 다르게 하여 하나의 api로 합칠 수 있었다.
기존 TagService코드 -> 수정 후 코드
TagService
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class TagService {
private final PostRepository postRepository;
private final PostLikeRepository postLikeRepository;
private final PostScrapRepository postScrapRepository;
private final ReportRepository reportRepository;
//전체 - 태그 순위
public List<String> allRankNumber() {
List<Post> postList = postRepository.findAll();
List<String> rankedIds = getHashTagsFromPosts(postList);
return getTopRankedTags(rankedIds, 6);
}
//카테고리 - 태그 순위
public List<String> categoryRankNumer (String category) {
List<Post> postList = postRepository.findAllBycategory(category);
List<String> rankedIds = getHashTagsFromPosts(postList);
return getTopRankedTags(rankedIds, 6);
}
//전체 - 태그별 post
public PostListResponse hashtagPostResponseDtos (int size, int page, String hashtagName, String type, User user
) {
Pageable pageable = PageRequest.of(page, size);
//인기순/최신순
Page<Post> postPage = type.equals("popular")
? postRepository.findAllByHashtagContainingOrderByPostViewCountDesc(hashtagName, pageable)
: postRepository.findAllByHashtagContainingOrderByCreatedAtDesc(hashtagName, pageable);
if (!postPage.hasContent()) {
throw new IllegalArgumentException("존재하지 않는 태그입니다.");
}
List<PostResultDto> postResultDtos =
postPage.getContent().stream()
.map(post -> mapToPostResultDto(post,user))
.collect(Collectors.toList());
return new PostListResponse("검색 조회 성공", postPage.getTotalPages(), postPage.getTotalElements(), size, postResultDtos);
}
//전체 - 태그별 post - +위치
public PostListResponse postLocationResponseDtos(int size, int page, String gu, User user) {
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
Page<Post> postPage = postRepository.findAllByGu(gu, pageable);
List<PostResultDto> postResultDtos =
postPage.getContent().stream()
.map(post -> mapToPostResultDto(post,user))
.collect(Collectors.toList());
return new PostListResponse("검색 조회 성공", postPage.getTotalPages(), postPage.getTotalElements(), size, postResultDtos);
}
//카테고리 - 태그별 포스트
public PostListResponse categoryHashtagPostResponseDtos (int size, int page, String hashtagName, String category, String type, User user) {
Pageable pageable = PageRequest.of(page, size);
Page<Post> postPage = type.equals("popular")
? postRepository.findAllByCategoryAndHashtagContainingOrderByPostViewCountDesc(category, hashtagName, pageable)
: postRepository.findAllByCategoryAndHashtagContainingOrderByCreatedAtDesc(category, hashtagName, pageable);
if (!postPage.hasContent()) {
throw new IllegalArgumentException("존재하지 않는 태그 혹은 존재하지 않는 카테고리 입니다.");
}
List<PostResultDto> postResultDtos = postPage.stream()
.map(post -> mapToPostResultDto(post,user))
.collect(Collectors.toList());
return new PostListResponse("검색 조회 성공", postPage.getTotalPages(), postPage.getTotalElements(), size, postResultDtos);
}
//카테고리 - 태그별 포스트 - +위치
public PostListResponse categoryLocationPostResponseDtos(int size, int page, String gu, String category, User user) {
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
Page<Post> postPage = postRepository.findAllByGuAndCategory(gu,category, pageable);
List<PostResultDto> postResultDtos =
postPage.getContent().stream()
.map(post -> mapToPostResultDto(post,user))
.collect(Collectors.toList());
return new PostListResponse("검색 조회 성공", postPage.getTotalPages(), postPage.getTotalElements(), size, postResultDtos);
}
//주어진 리스트에서 상위 N개의 요소를 선택하는 메서드
private List<String> getTopRankedTags(List<String> rankedIds, int limit) {
return rankedIds.stream().limit(limit).collect(Collectors.toList());
}
//PostResultDto 객체로 변환하는 메서드
private PostResultDto mapToPostResultDto(Post post, User user) {
UserResponseDto userResponseDto = new UserResponseDto(post.getUser());
PostInfoResponseDto postInfoResponseDto = new PostInfoResponseDto(post);
LocationResponseDto locationResponseDto = new LocationResponseDto(post.getLname(), post.getAddress(), post.getLat(), post.getLng(), post.getGu());
if (Objects.isNull(user)){
return new PostResultDto(userResponseDto, postInfoResponseDto, locationResponseDto, false,false,false);
}
boolean hasLikedPost = postLikeRepository.existsLikeByPostAndUser(post, user);
boolean hasScrapped = postScrapRepository.existsScrapByPostAndUser(post, user);
boolean hasReported = reportRepository.existsReportByPostAndUser(post,user);
return new PostResultDto(userResponseDto, postInfoResponseDto, locationResponseDto,hasLikedPost,hasScrapped,hasReported);
}
//postList에서 해시태그를 추출하고 인기순으로 정렬된 태그 목록을 반환
private List<String> getHashTagsFromPosts(List<Post> postList) {
Map<String, Integer> idFrequencyMap = new HashMap<>();
for (Post post : postList) {
if (Objects.isNull(post.getHashtag())) {
continue;
}
String hashTag = post.getHashtag();
String[] hashTagList = hashTag.split("#");
for (String tagName : hashTagList) {
if (!tagName.isEmpty()) {
idFrequencyMap.put(tagName, idFrequencyMap.getOrDefault(tagName, 0) + 1);
}
}
}
return idFrequencyMap.entrySet().stream()
.sorted((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue()))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
}
중복된 코드가 굉장히 많고 비슷한 api가 반복되어 가독성이 떨어진다.
수정 후 TagService
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class TagService {
private final PostRepository postRepository;
private final PostLikeRepository postLikeRepository;
private final PostScrapRepository postScrapRepository;
private final ReportRepository reportRepository;
// 태그 인기순위
public List<String> rankNumber(String category) {
List<Post> postList;
if (category == null || category.isEmpty()) {
postList = postRepository.findAll();
} else {
postList = postRepository.findAllBycategory(category);
}
List<String> rankedIds = getHashTagsFromPosts(postList);
return getTopRankedTags(rankedIds, 6);
}
// 태그별 포스트
public PostListResponse tagsPosts(int size, int page, String hashtagName, String type, String category, User user) {
Pageable pageable = PageRequest.of(page, size);
Page<Post> postPage;
if (category == null || category.isEmpty()) {
postPage = type.equals("popular")
? postRepository.findAllByHashtagContainingOrderByPostViewCountDesc(hashtagName, pageable)
: postRepository.findAllByHashtagContainingOrderByCreatedAtDesc(hashtagName, pageable);
} else {
postPage = type.equals("popular")
? postRepository.findAllByCategoryAndHashtagContainingOrderByPostViewCountDesc(category, hashtagName, pageable)
: postRepository.findAllByCategoryAndHashtagContainingOrderByCreatedAtDesc(category, hashtagName, pageable);
}
if (!postPage.hasContent()) {
throw new IllegalArgumentException("존재하지 않는 태그 혹은 존재하지 않는 카테고리입니다.");
}
List<PostResultDto> postResultDtos = postPage.stream()
.map(post -> mapToPostResultDto(post, user))
.collect(Collectors.toList());
return new PostListResponse("검색 조회 성공", postPage.getTotalPages(), postPage.getTotalElements(), size, postResultDtos);
}
// 태그별 포스트 - +위치
public PostListResponse postLocation(int size, int page, String gu, String category, User user) {
System.out.println("gu " + gu);
System.out.println("category " + category);
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
Page<Post> postPage;
if (category == null || category.isEmpty()) {
postPage = postRepository.findAllByGu(gu, pageable);
System.out.println("카테고리 없을 때");
} else {
postPage = postRepository.findAllByGuAndCategory(gu, category, pageable);
System.out.println("카테고리 있을 때");
}
List<PostResultDto> postResultDtos =
postPage.getContent().stream()
.map(post -> mapToPostResultDto(post, user))
.collect(Collectors.toList());
return new PostListResponse("검색 조회 성공", postPage.getTotalPages(), postPage.getTotalElements(), size, postResultDtos);
}
//주어진 리스트에서 상위 N개의 요소를 선택하는 메서드
private List<String> getTopRankedTags(List<String> rankedIds, int limit) {
return rankedIds.stream().limit(limit).collect(Collectors.toList());
}
//PostResultDto 객체로 변환하는 메서드
private PostResultDto mapToPostResultDto(Post post, User user) {
UserResponseDto userResponseDto = new UserResponseDto(post.getUser());
PostInfoResponseDto postInfoResponseDto = new PostInfoResponseDto(post);
LocationResponseDto locationResponseDto = new LocationResponseDto(post.getLname(), post.getAddress(), post.getLat(), post.getLng(), post.getGu());
if (Objects.isNull(user)){
return new PostResultDto(userResponseDto, postInfoResponseDto, locationResponseDto, false,false,false);
}
boolean hasLikedPost = postLikeRepository.existsLikeByPostAndUser(post, user);
boolean hasScrapped = postScrapRepository.existsScrapByPostAndUser(post, user);
boolean hasReported = reportRepository.existsReportByPostAndUser(post,user);
return new PostResultDto(userResponseDto, postInfoResponseDto, locationResponseDto,hasLikedPost,hasScrapped,hasReported);
}
//postList에서 해시태그를 추출하고 인기순으로 정렬된 태그 목록을 반환
private List<String> getHashTagsFromPosts(List<Post> postList) {
Map<String, Integer> idFrequencyMap = new HashMap<>();
for (Post post : postList) {
if (Objects.isNull(post.getHashtag())) {
continue;
}
String hashTag = post.getHashtag();
String[] hashTagList = hashTag.split("#");
for (String tagName : hashTagList) {
if (!tagName.isEmpty()) {
idFrequencyMap.put(tagName, idFrequencyMap.getOrDefault(tagName, 0) + 1);
}
}
}
return idFrequencyMap.entrySet().stream()
.sorted((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue()))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
}
코드의 길이는 크게 차이가 나지 않지만 api가 3개로 줄어서 가독성이 좋아졌다. if - else 문으로 user가 있을 때와 없을때 repository에서 post들을 다르게 가져오도록 하였다.
'코딩과 매일매일♥ > Seoulvival' 카테고리의 다른 글
230918 - 코드 리팩토링(폴더 구조 변경하기) (0) | 2023.09.18 |
---|---|
230906 - @Transactional을 걸어도 더티체킹이 안돼! (0) | 2023.09.06 |
230901 - Spring 의 BufferedImage로 S3 이미지 리사이징하기 (0) | 2023.09.01 |
230831 - 알림기능 구현하기(isRead true로 바꾸기 / SSE 연결하기 ) (0) | 2023.08.31 |
230830 - 알림기능 구현하기(해시태그 구독하기/ 알림 구독하기) (0) | 2023.08.31 |