Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/main/java/org/sopt/controller/ArticleController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import lombok.RequiredArgsConstructor;
import org.sopt.dto.article.ArticleRequestDto;
import org.sopt.dto.article.ArticleResponseDto;
import org.sopt.dto.comment.CommentRequestDto;
import org.sopt.dto.comment.CommentResponseDto;
import org.sopt.global.ApiResponse;
import org.sopt.service.ArticleService;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -44,4 +46,51 @@ public ResponseEntity<?> findArticleById(
.body(new ApiResponse<>(200,"아티클 조회 성공",body));
}

@PostMapping("/{articleId}/comments")
public ResponseEntity<?> addComment(
@PathVariable Long articleId,
@RequestBody String content,
@RequestBody Long memberId
) {
CommentRequestDto.create requestDto = new CommentRequestDto.create(articleId, content, memberId);
CommentResponseDto.CommentInfo body = articleService.createComment(requestDto);

return ResponseEntity.status(HttpStatus.CREATED)
.body(new ApiResponse<>(201, "댓글 작성 성공", body));
}

@GetMapping("/{articleId}/comments")
public ResponseEntity<?> findComments(
@PathVariable Long articleId
) {
CommentResponseDto.findComments body = articleService.findComments(articleId);

return ResponseEntity.status(HttpStatus.OK)
.body(new ApiResponse<>(200, "댓글 조회 성공", body));
}

@PatchMapping("/{articleId}/comments/{commentId}")
public ResponseEntity<?> updateComment(
@PathVariable Long articleId,
@PathVariable Long commentId,
@RequestBody String content
) {
CommentRequestDto.update requestDto = new CommentRequestDto.update(articleId, content, commentId);
CommentResponseDto.CommentInfo body = articleService.updateComment(requestDto);

return ResponseEntity.status(HttpStatus.OK)
.body(new ApiResponse<>(200, "댓글 수정 성공", body));
}

@DeleteMapping("/{articleId}/comments/{commentId}")
public ResponseEntity<?> deleteComment(
@PathVariable Long articleId,
@PathVariable Long commentId
) {
CommentRequestDto.delete requestDto = new CommentRequestDto.delete(commentId);
articleService.deleteComment(requestDto);

return ResponseEntity.status(HttpStatus.OK)
.body(new ApiResponse<>(200, "댓글 삭제 성공", null));
}
}
35 changes: 35 additions & 0 deletions src/main/java/org/sopt/domain/Comment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.sopt.domain;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor
public class Comment {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false, length = 300)
private String content;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "article_id")
private Article article;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "member_id")
private Member member;

public Comment(String content, Article article, Member member) {
this.content = content;
this.article = article;
this.member = member;
}

public void updateContent(String content) {
this.content = content;
}
}
19 changes: 19 additions & 0 deletions src/main/java/org/sopt/dto/comment/CommentRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.sopt.dto.comment;

public class CommentRequestDto {
public record create(
Long articleId,
String content,
Long memberId
){}

public record update(
Long articleId,
String content,
Long commentId
) {}

public record delete(
Long commentId
) {}
}
22 changes: 22 additions & 0 deletions src/main/java/org/sopt/dto/comment/CommentResponseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.sopt.dto.comment;

import org.sopt.domain.Comment;

import java.util.List;

public class CommentResponseDto {
public record CommentInfo(
String content
){}

public record findComments(
List<CommentInfo> comments
) {
public static findComments from(List<Comment> comments) {
return new findComments(comments.stream()
.map( comment -> new CommentInfo(comment.getContent()))
.toList()
);
}
}
}
26 changes: 26 additions & 0 deletions src/main/java/org/sopt/global/ExceptionAdvice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.sopt.global;

import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class ExceptionAdvice {
@ExceptionHandler(Exception.class)
public ApiResponse<?> handleException(Exception e) {
return new ApiResponse<>(
400,
e.getMessage(),
null
);
}

@ExceptionHandler(DataIntegrityViolationException.class)
public ApiResponse<?> handleException(DataIntegrityViolationException e) {
return new ApiResponse<>(
400,
"아티클 제목은 중복될 수 없습니다.",
null
);
}
}
12 changes: 12 additions & 0 deletions src/main/java/org/sopt/repository/CommentRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.sopt.repository;

import org.sopt.domain.Comment;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface CommentRepository extends JpaRepository<Comment, Long> {
List<Comment> findByArticleId(Long articleId);
}
42 changes: 42 additions & 0 deletions src/main/java/org/sopt/service/ArticleService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.sopt.domain.Article;
import org.sopt.domain.Comment;
import org.sopt.domain.Member;
import org.sopt.dto.article.ArticleRequestDto;
import org.sopt.dto.article.ArticleResponseDto;
import org.sopt.dto.comment.CommentRequestDto;
import org.sopt.dto.comment.CommentResponseDto;
import org.sopt.repository.ArticleRepository;
import org.sopt.repository.CommentRepository;
import org.sopt.repository.MemberRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -20,6 +24,7 @@
public class ArticleService {
private final ArticleRepository articleRepository;
private final MemberRepository memberRepository;
private final CommentRepository commentRepository;

public ArticleResponseDto.ArticleInfo findArticleByArticleId(ArticleRequestDto.findArticleByArticleId requestDto) {
Long articleId = requestDto.articleId();
Expand All @@ -45,4 +50,41 @@ public ArticleResponseDto.ArticleInfo createArticle(ArticleRequestDto.create req

return ArticleResponseDto.ArticleInfo.from(article);
}

public CommentResponseDto.CommentInfo createComment(CommentRequestDto.create requestDto) {
Long articleId = requestDto.articleId();
String content = requestDto.content();
Long memberId = requestDto.memberId();

Article article = articleRepository.findById(articleId)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 아티클 ID 입니다."));

Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 멤버 ID 입니다."));

Comment comment = new Comment(content, article, member);
commentRepository.save(comment);

return new CommentResponseDto.CommentInfo(comment.getContent());
}

public CommentResponseDto.findComments findComments(Long articleId) {
List<Comment> comments = commentRepository.findByArticleId(articleId);
return CommentResponseDto.findComments.from(comments);
}

public CommentResponseDto.CommentInfo updateComment(CommentRequestDto.update requestDto) {
Comment comment = commentRepository.findById(requestDto.commentId())
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 댓글 ID 입니다."));

comment.updateContent(requestDto.content());
return new CommentResponseDto.CommentInfo(comment.getContent());
}

public void deleteComment(CommentRequestDto.delete requestDto) {
Comment comment = commentRepository.findById(requestDto.commentId())
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 댓글 ID 입니다."));

commentRepository.delete(comment);
}
}
6 changes: 3 additions & 3 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ spring:
name: assignment

datasource:
url: jdbc:mysql://localhost:3306/assignment
username: root
password: root
url: jdbc:mysql://database-1.czecoeymovob.ap-northeast-2.rds.amazonaws.com:3306/assignment
username: admin
password: adminadmin
driver-class-name: com.mysql.cj.jdbc.Driver

jpa:
Expand Down