-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #68 from real-world-study/jinyoungchoi95-issue67
[jinyoungchoi95-issue67] Comment 추가/조회/삭제 기능 구현
- Loading branch information
Showing
17 changed files
with
1,128 additions
and
11 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
src/main/java/com/study/realworld/article/comment/controller/CommentController.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,50 @@ | ||
package com.study.realworld.article.comment.controller; | ||
|
||
import com.study.realworld.article.comment.controller.request.CommentCreateRequest; | ||
import com.study.realworld.article.comment.controller.response.CommentResponse; | ||
import com.study.realworld.article.comment.controller.response.CommentsResponse; | ||
import com.study.realworld.article.comment.domain.Comment; | ||
import com.study.realworld.article.comment.service.CommentService; | ||
import com.study.realworld.article.domain.Slug; | ||
import java.util.List; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RequestMapping("/api") | ||
@RestController | ||
public class CommentController { | ||
|
||
private final CommentService commentService; | ||
|
||
public CommentController(CommentService commentService) { | ||
this.commentService = commentService; | ||
} | ||
|
||
@GetMapping("/articles/{slug}/comments") | ||
public ResponseEntity<CommentsResponse> getCommentByArticleSlug(@PathVariable String slug) { | ||
List<Comment> comments = commentService.getCommentsByArticleSlug(Slug.of(slug)); | ||
return ResponseEntity.ok().body(CommentsResponse.fromComments(comments)); | ||
} | ||
|
||
@PostMapping("/articles/{slug}/comments") | ||
public ResponseEntity<CommentResponse> createComment(@PathVariable String slug, | ||
@RequestBody CommentCreateRequest request, | ||
@AuthenticationPrincipal Long loginId) { | ||
Comment comment = commentService.createComment(loginId, Slug.of(slug), request.toCommentBody()); | ||
return ResponseEntity.ok().body(CommentResponse.fromComment(comment)); | ||
} | ||
|
||
@DeleteMapping("/articles/{slug}/comments/{id}") | ||
public void deleteComment(@PathVariable String slug, @PathVariable Long id, | ||
@AuthenticationPrincipal Long loginId) { | ||
commentService.deleteCommentByCommentId(loginId, Slug.of(slug), id); | ||
} | ||
|
||
} |
22 changes: 22 additions & 0 deletions
22
...ain/java/com/study/realworld/article/comment/controller/request/CommentCreateRequest.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,22 @@ | ||
package com.study.realworld.article.comment.controller.request; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
import com.fasterxml.jackson.annotation.JsonTypeName; | ||
import com.study.realworld.article.comment.domain.CommentBody; | ||
|
||
@JsonTypeName(value = "comment") | ||
@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME) | ||
public class CommentCreateRequest { | ||
|
||
@JsonProperty("body") | ||
private String body; | ||
|
||
CommentCreateRequest() { | ||
} | ||
|
||
public CommentBody toCommentBody() { | ||
return CommentBody.of(body); | ||
} | ||
|
||
} |
68 changes: 68 additions & 0 deletions
68
src/main/java/com/study/realworld/article/comment/controller/response/CommentResponse.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,68 @@ | ||
package com.study.realworld.article.comment.controller.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonFormat; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import com.study.realworld.article.comment.domain.Comment; | ||
import com.study.realworld.article.comment.domain.CommentBody; | ||
import com.study.realworld.user.controller.response.ProfileResponse.ProfileResponseNested; | ||
import java.time.OffsetDateTime; | ||
|
||
public class CommentResponse { | ||
|
||
@JsonProperty("comment") | ||
private CommentResponseNested commentResponseNested; | ||
|
||
CommentResponse() { | ||
} | ||
|
||
private CommentResponse(CommentResponseNested commentResponseNested) { | ||
this.commentResponseNested = commentResponseNested; | ||
} | ||
|
||
public static CommentResponse fromComment(Comment comment) { | ||
return new CommentResponse(CommentResponseNested.fromComment(comment)); | ||
} | ||
|
||
public static class CommentResponseNested { | ||
|
||
@JsonProperty("id") | ||
private Long id; | ||
|
||
@JsonProperty("createdAt") | ||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC") | ||
private OffsetDateTime createdAt; | ||
|
||
@JsonProperty("updatedAt") | ||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC") | ||
private OffsetDateTime updatedAt; | ||
|
||
@JsonProperty("body") | ||
private CommentBody commentBody; | ||
|
||
@JsonProperty("author") | ||
private ProfileResponseNested profileResponseNested; | ||
|
||
CommentResponseNested() { | ||
} | ||
|
||
public CommentResponseNested(Long id, OffsetDateTime createdAt, OffsetDateTime updatedAt, | ||
CommentBody commentBody, | ||
ProfileResponseNested profileResponseNested) { | ||
this.id = id; | ||
this.createdAt = createdAt; | ||
this.updatedAt = updatedAt; | ||
this.commentBody = commentBody; | ||
this.profileResponseNested = profileResponseNested; | ||
} | ||
|
||
public static CommentResponseNested fromComment(Comment comment) { | ||
return new CommentResponseNested( | ||
comment.id(), | ||
comment.createdAt(), | ||
comment.updatedAt(), | ||
comment.commentBody(), | ||
ProfileResponseNested.ofProfile(comment.author().profile()) | ||
); | ||
} | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/com/study/realworld/article/comment/controller/response/CommentsResponse.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,29 @@ | ||
package com.study.realworld.article.comment.controller.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import com.study.realworld.article.comment.controller.response.CommentResponse.CommentResponseNested; | ||
import com.study.realworld.article.comment.domain.Comment; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class CommentsResponse { | ||
|
||
@JsonProperty("comments") | ||
private List<CommentResponseNested> commentResponseNesteds; | ||
|
||
CommentsResponse() { | ||
} | ||
|
||
private CommentsResponse(List<CommentResponseNested> commentResponseNesteds) { | ||
this.commentResponseNesteds = commentResponseNesteds; | ||
} | ||
|
||
public static CommentsResponse fromComments(List<Comment> comments) { | ||
return new CommentsResponse( | ||
comments.stream() | ||
.map(CommentResponseNested::fromComment) | ||
.collect(Collectors.toList()) | ||
); | ||
} | ||
|
||
} |
99 changes: 99 additions & 0 deletions
99
src/main/java/com/study/realworld/article/comment/domain/Comment.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,99 @@ | ||
package com.study.realworld.article.comment.domain; | ||
|
||
import com.study.realworld.article.domain.Article; | ||
import com.study.realworld.global.domain.BaseTimeEntity; | ||
import com.study.realworld.global.exception.BusinessException; | ||
import com.study.realworld.global.exception.ErrorCode; | ||
import com.study.realworld.user.domain.User; | ||
import java.time.OffsetDateTime; | ||
import java.util.Objects; | ||
import javax.persistence.Embedded; | ||
import javax.persistence.Entity; | ||
import javax.persistence.FetchType; | ||
import javax.persistence.ForeignKey; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.GenerationType; | ||
import javax.persistence.Id; | ||
import javax.persistence.JoinColumn; | ||
import javax.persistence.ManyToOne; | ||
import org.hibernate.annotations.Where; | ||
|
||
@Entity | ||
@Where(clause = "deleted_at is null") | ||
public class Comment extends BaseTimeEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@Embedded | ||
private CommentBody commentBody; | ||
|
||
@JoinColumn(name = "user_id", nullable = false, foreignKey = @ForeignKey(name = "fk_comment_to_user_id")) | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
private User author; | ||
|
||
@JoinColumn(name = "article_id", nullable = false, foreignKey = @ForeignKey(name = "fk_comment_to_article_id")) | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
private Article article; | ||
|
||
protected Comment() { | ||
} | ||
|
||
private Comment(CommentBody commentBody, User author, Article article) { | ||
this.commentBody = commentBody; | ||
this.author = author; | ||
this.article = article; | ||
} | ||
|
||
public static Comment from(CommentBody commentBody, User author, Article article) { | ||
return new Comment(commentBody, author, article); | ||
} | ||
|
||
public Long id() { | ||
return id; | ||
} | ||
|
||
public CommentBody commentBody() { | ||
return commentBody; | ||
} | ||
|
||
public User author() { | ||
return author; | ||
} | ||
|
||
public Article article() { | ||
return article; | ||
} | ||
|
||
public void deleteCommentByAuthor(User author) { | ||
checkCommentAuthor(author); | ||
|
||
saveDeletedTime(OffsetDateTime.now()); | ||
} | ||
|
||
private void checkCommentAuthor(User author) { | ||
if (!Objects.equals(this.author, author)) { | ||
throw new BusinessException(ErrorCode.INVALID_COMMENT_AUTHOR_DISMATCH); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Comment comment = (Comment) o; | ||
return Objects.equals(commentBody, comment.commentBody) && Objects | ||
.equals(author, comment.author) && Objects.equals(article, comment.article); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(commentBody, author, article); | ||
} | ||
|
||
} |
56 changes: 56 additions & 0 deletions
56
src/main/java/com/study/realworld/article/comment/domain/CommentBody.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,56 @@ | ||
package com.study.realworld.article.comment.domain; | ||
|
||
import static com.google.common.base.Preconditions.checkArgument; | ||
|
||
import com.fasterxml.jackson.annotation.JsonValue; | ||
import com.study.realworld.global.exception.ErrorCode; | ||
import java.util.Objects; | ||
import javax.persistence.Column; | ||
import javax.persistence.Embeddable; | ||
|
||
@Embeddable | ||
public class CommentBody { | ||
|
||
@Column(name = "body", columnDefinition = "text", nullable = false) | ||
private String body; | ||
|
||
protected CommentBody() { | ||
} | ||
|
||
private CommentBody(String body) { | ||
this.body = body; | ||
} | ||
|
||
public static CommentBody of(String body) { | ||
checkBody(body); | ||
|
||
return new CommentBody(body); | ||
} | ||
|
||
public static void checkBody(String body) { | ||
checkArgument(Objects.nonNull(body), ErrorCode.INVALID_COMMENT_BODY_NULL); | ||
} | ||
|
||
@JsonValue | ||
public String body() { | ||
return body; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
CommentBody body1 = (CommentBody) o; | ||
return Objects.equals(body, body1.body); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(body); | ||
} | ||
|
||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/study/realworld/article/comment/domain/CommentRepository.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,14 @@ | ||
package com.study.realworld.article.comment.domain; | ||
|
||
import com.study.realworld.article.domain.Article; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface CommentRepository extends JpaRepository<Comment, Long> { | ||
|
||
List<Comment> findAllByArticle(Article article); | ||
|
||
Optional<Comment> findByIdAndArticle(Long id, Article article); | ||
|
||
} |
Oops, something went wrong.