Skip to content

Commit ef0362a

Browse files
refactor: diary like 엔드포인트 toggle 형식으로 변경
# 변경점 👍 - 좋아요 추가/삭제 API 통합 (토글 형식) - Diary domain에서 model 객체 도입 및 생성자, update 리팩토링 - 제네릭 메서드를 활용한 DiaryService 중복 로직 제거 - DiaryEntity Content 필터링 로직 옮기기 (dto -> domain) # 비고 ✏ 크게 두 가지 영역에서 개선되었습니다. 먼저 좋아요 추가/삭제를 따로 두고 이미 처리되었을 때 예외처리하는 게 어색하게 느껴져서 토글 형식으로 하나의 엔드포인트로 통합했습니다. 나머지 변경사항들은 향후 기능 추가 도입/변경 전 Diary Domain 기존 코드 리팩토링입니다. 파라미터 개수가 너무 많은 함수들을 record 객체 및 함수 분리로 간결하게 만들었습니다. DTO가 비즈니스 로직을 담당하지 않도록 도메인 로직으로 옮기고, DTO 변환 쪽 코드 중복을 줄이기 위해 제네릭 메서드를 추가했습니다. --------- Co-authored-by: jinwon1234 <[email protected]>
1 parent 4d908bf commit ef0362a

24 files changed

+358
-350
lines changed

src/main/java/apptive/team5/diary/controller/DiaryController.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,7 @@
1111
import org.springframework.http.HttpStatus;
1212
import org.springframework.http.ResponseEntity;
1313
import org.springframework.security.core.annotation.AuthenticationPrincipal;
14-
import org.springframework.web.bind.annotation.DeleteMapping;
15-
import org.springframework.web.bind.annotation.GetMapping;
16-
import org.springframework.web.bind.annotation.PathVariable;
17-
import org.springframework.web.bind.annotation.PostMapping;
18-
import org.springframework.web.bind.annotation.PutMapping;
19-
import org.springframework.web.bind.annotation.RequestBody;
20-
import org.springframework.web.bind.annotation.RequestMapping;
21-
import org.springframework.web.bind.annotation.RequestParam;
22-
import org.springframework.web.bind.annotation.RestController;
14+
import org.springframework.web.bind.annotation.*;
2315

2416
import java.net.URI;
2517
import java.time.LocalDate;
@@ -97,8 +89,22 @@ public ResponseEntity<Void> createDiary(@AuthenticationPrincipal Long userId, @V
9789
return ResponseEntity.status(HttpStatus.CREATED).location(URI.create("/api/diaries/" + diary.getId())).build();
9890
}
9991

92+
@PatchMapping("/{diaryId}")
93+
public ResponseEntity<Void> patchDiary(
94+
@AuthenticationPrincipal
95+
Long userId,
96+
@PathVariable
97+
Long diaryId,
98+
@RequestBody
99+
DiaryUpdateRequestDto updateRequest
100+
) {
101+
diaryService.updateDiary(userId, diaryId, updateRequest);
102+
103+
return ResponseEntity.status(HttpStatus.OK).build();
104+
}
105+
100106
@PutMapping("/{diaryId}")
101-
public ResponseEntity<Void> updateDiary(
107+
public ResponseEntity<Void> putDiary(
102108
@AuthenticationPrincipal
103109
Long userId,
104110
@PathVariable
Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package apptive.team5.diary.controller;
22

3+
import apptive.team5.diary.dto.DiaryLikeResponseDto;
34
import apptive.team5.diary.service.DiaryLikeService;
45
import lombok.RequiredArgsConstructor;
56
import org.springframework.http.HttpStatus;
@@ -19,25 +20,14 @@ public class DiaryLikeController {
1920
private final DiaryLikeService diaryLikeService;
2021

2122
@PostMapping
22-
public ResponseEntity<Void> likeDiary(
23+
public ResponseEntity<DiaryLikeResponseDto> toggleDiaryLike(
2324
@AuthenticationPrincipal
2425
Long userId,
2526
@PathVariable
2627
Long diaryId
2728
) {
28-
diaryLikeService.likeDiary(userId, diaryId);
29+
DiaryLikeResponseDto responseDto = diaryLikeService.toggleDiaryLike(userId, diaryId);
2930

30-
return ResponseEntity.status(HttpStatus.CREATED).build();
31-
}
32-
33-
@DeleteMapping
34-
public ResponseEntity<Void> unlikeDiary(
35-
@AuthenticationPrincipal
36-
Long userId,
37-
@PathVariable
38-
Long diaryId
39-
) {
40-
diaryLikeService.unlikeDiary(userId, diaryId);
41-
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
31+
return ResponseEntity.status(HttpStatus.OK).body(responseDto);
4232
}
4333
}

src/main/java/apptive/team5/diary/domain/DiaryEntity.java

Lines changed: 47 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package apptive.team5.diary.domain;
22

3+
import apptive.team5.diary.domain.model.DiaryBasicInfo;
4+
import apptive.team5.diary.domain.model.DiaryInfo;
5+
import apptive.team5.diary.domain.model.MusicPlayInfo;
36
import apptive.team5.global.entity.BaseTimeEntity;
7+
import apptive.team5.global.exception.BadRequestException;
48
import apptive.team5.global.exception.ExceptionCode;
59
import apptive.team5.user.domain.UserEntity;
10+
import apptive.team5.diary.domain.model.MusicBasicInfo;
611
import jakarta.persistence.Column;
712
import jakarta.persistence.Entity;
813
import jakarta.persistence.EnumType;
914
import jakarta.persistence.Enumerated;
1015
import jakarta.persistence.FetchType;
11-
import jakarta.persistence.ForeignKey;
1216
import jakarta.persistence.GeneratedValue;
1317
import jakarta.persistence.GenerationType;
1418
import jakarta.persistence.Id;
@@ -39,9 +43,9 @@ public class DiaryEntity extends BaseTimeEntity {
3943
@Column(name = "diary_id")
4044
private Long id;
4145

42-
@Column(nullable = false, length = 255)
46+
@Column(nullable = false)
4347
private String musicTitle;
44-
@Column(nullable = false, length = 255)
48+
@Column(nullable = false)
4549
private String artist;
4650
@Column(columnDefinition = "TEXT", nullable = false)
4751
private String albumImageUrl;
@@ -69,33 +73,30 @@ public class DiaryEntity extends BaseTimeEntity {
6973
)
7074
private UserEntity user;
7175

76+
private static final String HIDDEN_CONTENT_DEFAULT_MESSAGE = "비공개 일기입니다.";
77+
7278
public DiaryEntity(
73-
String musicTitle,
74-
String artist,
75-
String albumImageUrl,
76-
String videoUrl,
77-
String content,
78-
DiaryScope scope,
79-
String duration,
80-
String totalDuration,
81-
String start,
82-
String end,
79+
DiaryInfo info,
8380
UserEntity user
8481
) {
85-
this(
86-
null,
87-
musicTitle,
88-
artist,
89-
albumImageUrl,
90-
videoUrl,
91-
content,
92-
scope,
93-
duration,
94-
totalDuration,
95-
start,
96-
end,
97-
user
98-
);
82+
this.user = user;
83+
update(info);
84+
}
85+
86+
public String getContentForViewer(Long viewerId) {
87+
if (isMyDiary(viewerId)) {
88+
return this.content;
89+
}
90+
91+
if (this.scope == DiaryScope.PRIVATE) {
92+
throw new BadRequestException(ExceptionCode.ACCESS_DENIED_DIARY.getDescription());
93+
}
94+
95+
if (this.scope == DiaryScope.KILLING_PART) {
96+
return HIDDEN_CONTENT_DEFAULT_MESSAGE;
97+
}
98+
99+
return this.content;
99100
}
100101

101102
public void validateOwner(UserEntity user) {
@@ -112,36 +113,29 @@ private boolean isOwner(Long userId) {
112113
return this.user.getId().equals(userId);
113114
}
114115

115-
public boolean isScopeKillingPart() {
116-
return this.scope == DiaryScope.KILLING_PART;
116+
public void update(DiaryInfo info) {
117+
updateMusicBaseInfo(info.musicBasicInfo());
118+
updateDiaryBasicInfo(info.diaryBasicInfo());
119+
updateMusicPlayInfo(info.musicPlayInfo());
117120
}
118121

119-
public boolean isScopePrivate() {
120-
return this.scope == DiaryScope.PRIVATE;
122+
public void updateMusicBaseInfo(MusicBasicInfo musicBasicInfo) {
123+
updateMusicTitle(musicBasicInfo.musicTitle());
124+
updateArtist(musicBasicInfo.artist());
125+
updateAlbumImageUrl(musicBasicInfo.albumImageUrl());
126+
updateVideoUrl(musicBasicInfo.videoUrl());
121127
}
122128

123-
public void update(
124-
String musicTitle,
125-
String artist,
126-
String albumImageUrl,
127-
String videoUrl,
128-
String content,
129-
DiaryScope scope,
130-
String duration,
131-
String totalDuration,
132-
String start,
133-
String end
134-
) {
135-
updateMusicTitle(musicTitle);
136-
updateArtist(artist);
137-
updateAlbumImageUrl(albumImageUrl);
138-
updateVideoUrl(videoUrl);
139-
updateContent(content);
140-
updateScope(scope);
141-
updateDuration(duration);
142-
updateTotalDuration(totalDuration);
143-
updateStart(start);
144-
updateEnd(end);
129+
public void updateDiaryBasicInfo(DiaryBasicInfo diaryBasicInfo) {
130+
updateContent(diaryBasicInfo.content());
131+
updateScope(diaryBasicInfo.scope());
132+
}
133+
134+
public void updateMusicPlayInfo(MusicPlayInfo musicPlayInfo) {
135+
updateDuration(musicPlayInfo.duration());
136+
updateTotalDuration(musicPlayInfo.totalDuration());
137+
updateStart(musicPlayInfo.start());
138+
updateEnd(musicPlayInfo.end());
145139
}
146140

147141
private void updateMusicTitle(String musicTitle) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package apptive.team5.diary.domain.model;
2+
3+
import apptive.team5.diary.domain.DiaryScope;
4+
5+
public record DiaryBasicInfo(
6+
String content,
7+
DiaryScope scope
8+
) {
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package apptive.team5.diary.domain.model;
2+
3+
public record DiaryInfo(
4+
MusicBasicInfo musicBasicInfo,
5+
DiaryBasicInfo diaryBasicInfo,
6+
MusicPlayInfo musicPlayInfo
7+
) {
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package apptive.team5.diary.domain.model;
2+
3+
public record MusicBasicInfo(
4+
String musicTitle,
5+
String artist,
6+
String albumImageUrl,
7+
String videoUrl
8+
) {
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package apptive.team5.diary.domain.model;
2+
3+
public record MusicPlayInfo(
4+
String duration,
5+
String totalDuration,
6+
String start,
7+
String end
8+
) {
9+
}

src/main/java/apptive/team5/diary/dto/DiaryCreateRequest.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
import apptive.team5.diary.domain.DiaryEntity;
44
import apptive.team5.diary.domain.DiaryScope;
5+
import apptive.team5.diary.domain.model.DiaryBasicInfo;
6+
import apptive.team5.diary.domain.model.DiaryInfo;
7+
import apptive.team5.diary.domain.model.MusicBasicInfo;
8+
import apptive.team5.diary.domain.model.MusicPlayInfo;
59
import apptive.team5.user.domain.UserEntity;
610
import jakarta.validation.constraints.NotBlank;
711
import jakarta.validation.constraints.NotNull;
@@ -28,18 +32,28 @@ public record DiaryCreateRequest(
2832
@NotBlank(message = "킬링파트 종료 시간은 필수 입력입니다.")
2933
String end
3034
) {
31-
public static DiaryEntity toEntity(DiaryCreateRequest diaryRequest, UserEntity user) {
35+
public DiaryEntity toEntity(UserEntity user) {
36+
DiaryInfo diaryInfo = new DiaryInfo(
37+
new MusicBasicInfo(
38+
musicTitle,
39+
artist,
40+
albumImageUrl,
41+
videoUrl
42+
),
43+
new DiaryBasicInfo(
44+
content,
45+
scope
46+
),
47+
new MusicPlayInfo(
48+
duration,
49+
totalDuration,
50+
start,
51+
end
52+
)
53+
);
54+
3255
return new DiaryEntity(
33-
diaryRequest.musicTitle,
34-
diaryRequest.artist,
35-
diaryRequest.albumImageUrl,
36-
diaryRequest.videoUrl,
37-
diaryRequest.content,
38-
diaryRequest.scope,
39-
diaryRequest.duration,
40-
diaryRequest.totalDuration,
41-
diaryRequest.start,
42-
diaryRequest.end,
56+
diaryInfo,
4357
user
4458
);
4559
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package apptive.team5.diary.dto;
2+
3+
public record DiaryLikeResponseDto(
4+
boolean isLiked
5+
) {
6+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package apptive.team5.diary.dto;
2+
3+
public interface DiaryResponseDto {
4+
}

0 commit comments

Comments
 (0)