[이재훈_BackEnd] 6주차 과제제출 - #11
Conversation
| public class HelloController { | ||
|
|
||
| private final Map<Long, Article> articles = new HashMap<>(); | ||
| private final AtomicLong idGenerator = new AtomicLong(1); |
There was a problem hiding this comment.
일반적인 자료형 Long이 아니라 AtomicLong을 도입한 이유가 있으신가요?!
| @ResponseBody | ||
| @GetMapping("/article/{id}") | ||
| public ResponseEntity<Article> getArticle(@PathVariable Long id) { | ||
| Article article = articles.get(id); | ||
|
|
||
| if (article == null) { | ||
| return ResponseEntity.notFound().build(); | ||
| } | ||
|
|
||
| return ResponseEntity.ok(article); | ||
| } |
There was a problem hiding this comment.
이 아래의 API는 모두 Article과 관련된 클래스라 단일 책임 원칙에 따라 파일을 ArticleController로 분리하는 것은 어떻게 생각하시나요?
| } | ||
|
|
||
| @ResponseBody | ||
| @PostMapping("/article") |
There was a problem hiding this comment.
모두 /article로 특정 경로가 중복되는데 공통으로 분리하는 방법이 있지않을까요??
| return ResponseEntity.noContent().build(); | ||
| } | ||
|
|
||
| static class Article { |
There was a problem hiding this comment.
Article 클래스 역시 파일을 분리해주시면 돼요
| public Long getId() { | ||
| return id; | ||
| } | ||
|
|
||
| public String getDescription() { | ||
| return description; | ||
| } |
There was a problem hiding this comment.
getXXX() 와 같은 메소드를 반복적으로 만들기 힘들다면 Lombok 이라는 라이브러리가 있는데, 이를 활용해보시는 것을 추천드려요!
오히려 사용을 적극 권장드립니다
| } | ||
| } | ||
|
|
||
| static class ArticleRequest { |
| @ResponseBody | ||
| @GetMapping("/articles") | ||
| public Collection<Article> getArticles() { | ||
| return articleService.getArticles(); | ||
| } |
| @ResponseBody | ||
| @GetMapping("/articles/{id}") | ||
| public ResponseEntity<Article> getArticle(@PathVariable Long id) { | ||
| return articleService.getArticle(id) | ||
| .map(ResponseEntity::ok) | ||
| .orElseGet(() -> ResponseEntity.notFound().build()); | ||
| } |
| } | ||
|
|
||
| return ResponseEntity.noContent().build(); | ||
| } | ||
| } No newline at end of file |
| @Controller | ||
| public class ArticleController { | ||
|
|
||
| private final ArticleService articleService; | ||
|
|
||
| public ArticleController(ArticleService articleService) { | ||
| this.articleService = articleService; | ||
| } | ||
|
|
There was a problem hiding this comment.
현재 Controller 안에는 @ResponseBody 가 수식된 메소드가 많으니
@RestController 로 바꾸고, posts() 메소드만 별도 Controller 로 분리하는 것도 방법입니다
| public ArticleRepository() { | ||
| save(new ArticleRequestData(1L, 1L, "제목0", "내용입니다.")); | ||
| save(new ArticleRequestData(1L, 1L, "제목1", "내용입니다 내용입니다.")); | ||
| save(new ArticleRequestData(1L, 1L, "제목2", "내용입니다 내용입니다 내용입니다.")); | ||
| } |
There was a problem hiding this comment.
앱 실행 시 초기 데이터를 삽입하고자 할 때
CommandLineRunner 를 활용해보시는 것을 추천합니다
여기 한번 참고 부탁드립니다
| public Optional<Article> update(Long id, ArticleRequestData request) { | ||
| Article oldArticle = articles.get(id); | ||
|
|
||
| if (oldArticle == null) { | ||
| return Optional.empty(); | ||
| } | ||
|
|
||
| Article updatedArticle = new Article( | ||
| id, | ||
| request.authorId(), | ||
| request.boardId(), | ||
| request.title(), | ||
| request.content(), | ||
| oldArticle.getCreatedAt(), | ||
| LocalDate.now().toString() | ||
| ); | ||
|
|
||
| articles.put(id, updatedArticle); | ||
| return Optional.of(updatedArticle); | ||
| } |
There was a problem hiding this comment.
update와 같은 경우에는 새 객체를 만드는 것보다는
Article 클래스 내에 수정 메소드를 별도로 만들어서 처리하는 것이 좀더 효율적입니다!
Article 클래스 내에는 예시로 아래 처럼 구현해주시면 됩니다
public void update(String title, String content) {
this.title = title;
this.content = content;
this.updatedAt = LocalDate.now().toString();
}
| public record ArticleRequestData(Long authorId, Long boardId, String title, String content) { | ||
| } | ||
| } No newline at end of file |
There was a problem hiding this comment.
ArticleRequest 를 작성해주신 것으로 보이는데 별도로 AritcleRequestData 를 내부에 record 로 작성해주신 이유가 있을까요?
현재 ArticleRequest 가 사용되는 부분을 찾을 수가 없는데 둘 중 하나만 유지해도 충분할 것으로 보입니다
| package com.example.demo.article; | ||
|
|
||
| public class ArticleRequest { | ||
|
|
||
| private Long authorId; | ||
| private Long boardId; | ||
| private String title; | ||
| private String content; | ||
|
|
||
| public ArticleRequest() { | ||
| } | ||
|
|
There was a problem hiding this comment.
Request, Response 와 같은 DTO들의 경우에는 한 번 필드에 값이 입력되면 변하지 않으므로 보통 record 로 많이 만들어줍니다
그리고 DTO 내부들에 toEntity(), from() 등의 정적 팩토리 메소드들을 만들어줄 수도 있는데, 이들의 용도는 객체 -> DTO 또는 DTO -> 객체 로의 변환 과정을 보다 용이하게 하도록 도와주는 것입니다
자세한 부분은 링크 참고 부탁드립니다
| private ArticleRepository.ArticleRequestData toData(ArticleRequest request) { | ||
| return new ArticleRepository.ArticleRequestData( | ||
| request.getAuthorId(), | ||
| request.getBoardId(), | ||
| request.getTitle(), | ||
| request.getContent() | ||
| ); | ||
| } |
There was a problem hiding this comment.
상술했던 것과 마찬가지로, ArticleRequest, ArticleRequestData 두 개 모두를 유지하는 이유에 대해 여쭙고 싶습니다..!
No description provided.