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
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## TODO List
- [ ] 게시글 작성 API 구현
- [ ] 게시글 수정 API 구현
- [ ] 게시글 삭제 API 구현
- [ ] 게시글 삭제 시 예외 케이스 구현
- [ ] 게시글이 이미 삭제된 경우 예외 처리
- [ ] 존재하지 않는 게시글 삭제 요청 시 예외 처리
- [ ] 게시글 단건 조회 API 구현
- [ ] 게시글에 포함된 모든 댓글 목록을 조회

- [ ] 댓글 작성 API 구현
- [ ] 댓글 수정 API 구현
- [ ] 댓글 삭제 API 구현

...
---

## 구현 시 어렵거나 이해가 되지 않는 부분
- 예외를 어떻게 던지고 처리해야 할지 모르겠다.
- null 값 처리
- DTO 변환 로직 구현
- Optional을 활용한 코드
- 트랜잭션과 @Transactional 사용법 - 클래스 레벨에 사용해도 되는지
2 changes: 2 additions & 0 deletions src/main/java/io/sparta/board/BoardApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableJpaAuditing
public class BoardApplication {

public static void main(String[] args) {
Expand Down
53 changes: 53 additions & 0 deletions src/main/java/io/sparta/board/controller/CommentController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.sparta.board.controller;

import io.sparta.board.dto.CommentRequestDto;
import io.sparta.board.dto.CommentResponseDto;
import io.sparta.board.entity.Comment;
import io.sparta.board.service.CommentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("/posts/{postId}/comments")
@RequiredArgsConstructor
public class CommentController {
private final CommentService commentService;

/*
TODO 댓글 등록
- 댓글 내용은 필수 항목
- 댓글 등록 일자 자동 기록
*/
@PostMapping
public ResponseEntity<CommentResponseDto> createComment(
@RequestBody CommentRequestDto req, @PathVariable UUID postId) {
CommentResponseDto createComment = commentService.createComment(req, postId);
return ResponseEntity.ok(createComment);
}

/*
TODO 댓글 수정
- 댓글 내용만 수정 가능
- 댓글 수정 일자 자동 기록
*/
@PutMapping("/{commentId}")
public ResponseEntity<CommentResponseDto> updateComment(
@PathVariable UUID commentId, @RequestBody CommentRequestDto req) {
CommentResponseDto updatedComment = commentService.updateComment(commentId, req);
return ResponseEntity.ok(updatedComment);
}

/*
TODO 댓글 삭제
- 삭제 후 복구 불가능
- 댓글 삭제 시 삭제 상태에 대한 변경만 처리(soft-delete)
*/
@DeleteMapping("/{commentId}")
public ResponseEntity<CommentResponseDto> deleteComment(@PathVariable UUID commentId) {
commentService.deleteComment(commentId);
return ResponseEntity.noContent().build();
}
}
66 changes: 66 additions & 0 deletions src/main/java/io/sparta/board/controller/PostController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package io.sparta.board.controller;

import io.sparta.board.dto.PostRequestDto;
import io.sparta.board.dto.PostResponseDto;
import io.sparta.board.entity.Post;
import io.sparta.board.repository.PostRepository;
import io.sparta.board.service.PostService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("/posts")
@RequiredArgsConstructor
public class PostController {
private final PostService postService;

/*
TODO 게시글 작성
- 게시글 제목, 내용은 필수 항목
- 게시글 작성 일자 자동 기록
*/
@PostMapping
public ResponseEntity<PostResponseDto> createPost(@RequestBody PostRequestDto requestDto) {
PostResponseDto createdPost = postService.createPost(requestDto);
return ResponseEntity.ok(createdPost);
}

/*
TODO 게시글 수정
- 제목과 내용만 수정 가능
- 게시글 수정 일자 자동 기록
*/
@PutMapping("/{id}")
public ResponseEntity<PostResponseDto> updatePost(@PathVariable UUID id,
@RequestBody PostRequestDto requestDto) {
PostResponseDto updatedPost = postService.updatePost(id, requestDto);
return ResponseEntity.ok(updatedPost);
}

/*
TODO 게시글 삭제

- 삭제 시 게시글과 함께 해당 게시글의 모든 댓글도 삭제 처리
- 삭제 후 복구 불가능
- 게시글 삭제 시 삭제 상태에 대한 변경만 처리(soft-delete)
*/
@DeleteMapping("/{id}")
public ResponseEntity<Void> deletePost(@PathVariable UUID id) {
postService.deletePost(id);
return ResponseEntity.noContent().build();
}

/*
TODO 게시글 단건 조회
- 게시글에 포함된 모든 댓글 목록을 조회
- 삭제된 데이터는 조회 불가능
*/
@GetMapping("/{id}")
public ResponseEntity<PostResponseDto> getPostById(@PathVariable UUID id) {
PostResponseDto getPost = postService.getPostById(id);
return ResponseEntity.ok(getPost);
}
}
12 changes: 12 additions & 0 deletions src/main/java/io/sparta/board/dto/CommentRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.sparta.board.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class CommentRequestDto {
private String content;
}
20 changes: 20 additions & 0 deletions src/main/java/io/sparta/board/dto/CommentResponseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.sparta.board.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;
import java.util.UUID;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CommentResponseDto {
private UUID id;
private String content;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
13 changes: 13 additions & 0 deletions src/main/java/io/sparta/board/dto/PostRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.sparta.board.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class PostRequestDto {
private String title;
private String content;
}
24 changes: 24 additions & 0 deletions src/main/java/io/sparta/board/dto/PostResponseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.sparta.board.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class PostResponseDto {
private UUID id;
private String title;
private String content;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;

private List<CommentResponseDto> comments;
}
22 changes: 22 additions & 0 deletions src/main/java/io/sparta/board/entity/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.sparta.board.entity;

import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Getter
public class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdAt;

@LastModifiedDate
private LocalDateTime updatedAt;
}
35 changes: 35 additions & 0 deletions src/main/java/io/sparta/board/entity/Comment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.sparta.board.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.sql.Timestamp;
import java.util.UUID;

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "p_comment")
public class Comment extends BaseEntity {
@Id
@GeneratedValue
private UUID id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id", nullable = false)
private Post post;

@Column(nullable = false, columnDefinition = "TEXT")
private String content;

@Column(nullable = false)
private boolean deleted=false;

}
37 changes: 37 additions & 0 deletions src/main/java/io/sparta/board/entity/Post.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.sparta.board.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.sql.Timestamp;
import java.util.List;
import java.util.UUID;

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "p_post")
public class Post extends BaseEntity {
@Id
@GeneratedValue
private UUID id;

@Column(nullable = false, length = 100)
private String title;

@Column(nullable = false, columnDefinition = "TEXT")
private String content;

@Column(nullable = false)
private boolean deleted = false;

@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> comments;
}
14 changes: 14 additions & 0 deletions src/main/java/io/sparta/board/repository/CommentRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.sparta.board.repository;

import io.sparta.board.entity.Comment;
import io.sparta.board.entity.Post;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Repository
public interface CommentRepository extends JpaRepository<Comment, UUID> {
}
13 changes: 13 additions & 0 deletions src/main/java/io/sparta/board/repository/PostRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.sparta.board.repository;

import io.sparta.board.entity.Post;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;
import java.util.UUID;

@Repository
public interface PostRepository extends JpaRepository<Post, UUID> {
Optional<Post> findByIdAndDeletedFalse(UUID id);
}
Loading