-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Article CRUD and Comment CRUD #13
base: main
Are you sure you want to change the base?
Changes from all commits
e313192
fe9b97e
d85b433
5a563f8
71c21fb
10e249c
67e0277
247011c
c305540
bdc530d
e76bd33
e33831b
55fa8a2
3d14903
ea9c945
6630e49
8a8d54a
3d08cfe
877e468
a72394c
5d5be0a
9c66e7c
dd1ba9b
48c9199
d2f4145
7c153c1
2073414
ac9ac26
3b99ccf
6fd13b0
a8d6e2f
66e9e2c
122bb7b
d39ccfd
c510964
79683bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package com.gdsc.blog.article.controller; | ||
|
||
import com.gdsc.blog.article.dto.ArticleCreateDto; | ||
import com.gdsc.blog.article.dto.ArticleUpdateDto; | ||
import com.gdsc.blog.article.entity.Article; | ||
import com.gdsc.blog.article.service.ArticleService; | ||
import com.gdsc.blog.user.entity.User; | ||
import com.gdsc.blog.user.service.UserService; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.Parameter; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.security.access.prepost.PreAuthorize; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.stereotype.Controller; | ||
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; | ||
|
||
@Controller | ||
@RequestMapping("/api/article") | ||
@RestController | ||
@RequiredArgsConstructor | ||
@Tag(name = "게시글 Controller", description = "Article controller API") | ||
@Slf4j | ||
public class ArticleController { | ||
|
||
private final ArticleService articleService; | ||
private final UserService userService; | ||
|
||
/** | ||
* 게시글 생성 | ||
* @param dto 게시글 생성 정보 | ||
* @return 생성된 게시글 | ||
*/ | ||
@PostMapping //컨트롤러 메핑 | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") //권한 설정 | ||
@Operation(summary = "게시글 생성") //swagger 설명 | ||
public Article createArticle( | ||
@Parameter(name="게시글 생성 DTO") @RequestBody ArticleCreateDto dto){ | ||
//로그인 유저 정보 가져오기 | ||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||
String userName = authentication.getName(); | ||
User user = userService.getUserByName(userName); //유저 이름 가져오기 | ||
|
||
return articleService.createArticle(dto, user); | ||
} | ||
|
||
/** | ||
* 모든 게시글 조회 | ||
* @param req HTTP 파싱 객체 | ||
* @return 게시글 목록 | ||
*/ | ||
@GetMapping("/get") | ||
@Operation(summary = "모든 게시글 조회") | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
public List<Article> getUserArticle( | ||
@Parameter(hidden = true) HttpServletRequest req | ||
) { | ||
User user = userService.whoami(req); //로그인 유저 정보 가져오기 | ||
|
||
return articleService.getUserArticle(user); | ||
} | ||
|
||
/** | ||
* id로 게시글 조회 | ||
* @param id 게시글 id | ||
* @param req HTTP 파싱 객체 | ||
* @return 게시글 | ||
*/ | ||
@GetMapping("/get/id/{id}") | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
@Operation(summary = "id로 게시글 조회") | ||
public Article getArticleById( | ||
@Parameter(description = "게시글 id") @PathVariable("id") Long id, | ||
@Parameter(hidden = true) HttpServletRequest req){ | ||
return articleService.getArticleById(id); | ||
} | ||
|
||
/** | ||
* 제목으로 게시글 조회 | ||
* @param title 게시글 제목 | ||
* @param req HTTP 파싱 객체 | ||
* @return 게시글 | ||
*/ | ||
@GetMapping("/get/title/{title}") | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
@Operation(summary = "제목으로 게시글 조회") | ||
public Article getArticleByTitle( | ||
@Parameter(description = "게시글 제목") @PathVariable(value = "title") String title, | ||
@Parameter(hidden = true) HttpServletRequest req){ | ||
return articleService.getArticleByTitle(title); | ||
} | ||
|
||
/** | ||
* 게시글 수정 | ||
* @param id 게시글 id | ||
* @param dto 게시글 수정 정보 | ||
* @param req HTTP 파싱 객체 | ||
*/ | ||
@PostMapping("/patch/{id}") //생성 & 수정은 PostMapping | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
@Operation(summary = "게시글 수정") | ||
public void updateArticle( | ||
@Parameter(description = "게시글 id") @PathVariable(value = "id") Long id, | ||
@Parameter(name="게시글 수정 DTO") @RequestBody ArticleUpdateDto dto, | ||
@Parameter(hidden = true) HttpServletRequest req) { | ||
User user = userService.whoami(req); | ||
|
||
articleService.updateArticle(id, dto); | ||
} | ||
|
||
/** | ||
* 게시글 삭제 | ||
* @param id 게시글 id | ||
* @param req HTTP 파싱 객체 | ||
*/ | ||
@GetMapping("/delete/{id}") | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
@Operation(summary = "게시글 삭제") | ||
public void deleteArticle( | ||
@Parameter(description = "게시글 id") @PathVariable(value = "id") Long id, | ||
@Parameter(hidden = true) HttpServletRequest req) { | ||
User user = userService.whoami(req); | ||
|
||
Article article = articleService.getArticleById(id); | ||
|
||
articleService.deleteArticle(article); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.gdsc.blog.article.dto; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@Builder | ||
@Getter | ||
@Setter | ||
public class ArticleCreateDto { | ||
@Schema(description = "제목", example = "게시글 제목") | ||
public String title; | ||
|
||
@Schema(description = "내용", example = "게시글 내용") | ||
public String content; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.gdsc.blog.article.dto; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@Builder | ||
@Getter | ||
@Setter | ||
public class ArticleUpdateDto { | ||
@Schema(description = "수정할 제목", example = "수정된 게시글 제목") | ||
public String title; | ||
|
||
@Schema(description = "수정할 내용", example = "수정된 게시글 내용") | ||
public String content; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.gdsc.blog.article.entity; | ||
|
||
import com.gdsc.blog.base.entity.Base; | ||
import com.gdsc.blog.comment.entity.Comment; | ||
import jakarta.persistence.CascadeType; | ||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.OneToMany; | ||
import jakarta.persistence.Table; | ||
import java.util.List; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
@Entity | ||
@NoArgsConstructor | ||
@AllArgsConstructor //생성자 자동 생성 | ||
@Getter | ||
@Setter | ||
@SuperBuilder | ||
@Table(name = "articles") | ||
public class Article extends Base { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; //id | ||
|
||
@Column(length = 200) | ||
private String title; //제목 | ||
|
||
@OneToMany(mappedBy = "article", cascade = CascadeType.REMOVE) | ||
private List<Comment> comments; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.gdsc.blog.article.repository; | ||
|
||
import com.gdsc.blog.article.entity.Article; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface ArticleRepository extends JpaRepository<Article, Long> { | ||
Optional<Article> findByTitle(String title); | ||
List<Article> findByTitleLikeOrContentLike(String title, String content); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런 스타일 관련 변경점은 새로운 PR을 통해 작성하는게 좋아요!
다른 사람과 작업을 할 때, 이 부분을 예를 들자면, 어플리케이션 실행 전 로그를 남기는 등의 동작을 추가하게 된다면 Conflict가 나게 되겠죠?