# 서비스 레이어로 리팩토링
## 미션
---
기존 댓글 생성 코드를 리팩토링 하시오. 서비스 레이어를 사용 할 것!

## 개념
---
#### ⭐️ 레이어 아키텍처
스프링 부트는 크게 5가지의 컴포넌트로 구성 된다. 이들을 그룹화 하면 크게 3개의 레이어(layer)로 구분된다. 클라이언트와 맞닿은 웹 레이어(Web Layer), 비즈니스 처리 흐름을 담당하는 서비스 레이어(Service Layer), 데이터베이스와 소통하는 리파지터리 레이어(Repository Layer)이다.

## 튜토리얼
---
#### ⭐️ API 컨트롤러
1) 리팩토링: "api/CommentApiController"
```
@Slf4j
@RequiredArgsConstructor
@RestController
public class CommentApiController {
private final CommentService commentService; // 서비스 레이어 객체
@PostMapping("/api/comments/{articleId}")
public Long create(@PathVariable Long articleId,
@RequestBody CommentForm form) {
// 서비스 객체가 댓글 생성
Comment saved = commentService.create(articleId, form);
log.info("saved: " + saved.toString());
return saved.getId();
}
}
```
#### ⭐️ 서비스 클래스
2) 생성: "service/CommentService"
```
@Slf4j
@RequiredArgsConstructor
@Service
public class CommentService {
private final ArticleRepository articleRepository;
private final CommentRepository commentRepository;
@Transactional
public Comment create(Long articleId, CommentForm form) {
// 폼 데이터를 엔티티 객체로 변경
log.info("form: " + form.toString());
Comment comment = form.toEntity();
log.info("comment: " + comment.toString());
// 댓글이 달릴 게시글을 가져옴!
Article article = articleRepository.findById(articleId)
.orElseThrow(
() -> new IllegalArgumentException("댓글을 작성할 Article이 없습니다.")
);
// 댓글 엔티티에 게시글 엔티티를 등록
comment.stickTo(article);
log.info("written: " + comment.toString());
return comment;
}
}
```
#### ⭐️ 확인하기
3) 댓글 작성

4) 레코드 확인: "생성되지 않음"

## 훈련하기
---
- 진행 4) 에서 comment가 등록되지 않은 이유를 분석하고, 이를 해결하시오.

## 면접 준비
---
- 컨트롤러, 서비스, 리파지터리의 역할은 무엇?
- 각각의 레이어로 나누면 어떤 점이 좋음?