들어가며
GitHub 저장소
구현 기능들
궁금한 것
코드 리뷰
후기
📆 기간 : 2023.04.25 ~ 2023.04.27
들어가며
장바구니 미션을 연어와 진행하게 되었다. 연어는 인호형 군대 후임이라서 알게 되었었는데 그래서 조금 더 빠르게 친해질 수 있었던 것 같다. 연어는 인텔리제이도 잘 다루었고 자바, 스프링도 잘 다루었다. 연어를 보면서 나도 인텔리제이 단축키를 활용해서 더 잘 해야겠다고 결심하게 되었다. 호호. 모르는 것에 대해 물어볼 때 마다 답을 잘해주어서 고마웠다~그리고 재미있었다.
GitHub 저장소
구현 기능 목록
상품 목록 페이지 연동
html 파일을 수정하여 상품 목록 페이지를 연동하였다. 나는 html, js에 관한 지식이 없었다. 연어 덕분에 조금 이해하고 해결할 수 있었던 것 같다. 백엔드도 어느정도 html을 비롯한 프론트 코드를 대충은 알아야 할 것 같다 . .
@GetMapping("/")
public String showProductsList(Model model) {
model.addAttribute("products", productService.findProducts());
return "index";
}
정적 파일로 이동할 수 있도록 처리하였다. Model 이라는 것도 처음 접해서 애를 먹었던 것 같다.
상품 관리 CRUD API 작성
상품 관련 추가, 조회, 수정, 삭제 Api를 작성하였다. 사실 조회 Api같은 경우에는 필요하지는 않지만 구현하였다.
@PostMapping("/product")
public ResponseEntity<Void> createProduct(@RequestBody @Valid ProductSaveRequestDto productSaveRequestDto) {
productService.addProduct(productSaveRequestDto);
return ResponseEntity.noContent().build();
}
@GetMapping("/products")
public ResponseEntity<List<ProductResponseDto>> getProducts() {
List<ProductResponseDto> products = productService.findProducts();
return ResponseEntity.ok(products);
}
@PutMapping("/product/{id}")
public ResponseEntity<Void> updateProduct(@PathVariable Long id, @RequestBody ProductUpdateRequestDto productUpdateRequestDto) {
productService.updateProduct(id, productUpdateRequestDto);
return ResponseEntity.noContent().build();
}
@DeleteMapping("/product/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
productService.deleteProduct(id);
return ResponseEntity.noContent().build();
}
put같은 경우에는 단순하게 uri 를 "/product" 로 진행하였는데 restful하게 하라는 말을 듣고 수정하였다.
또한 반환 값으로 204를 넘겨주도록 하였다!
관리자 도구 페이지 연동
admin.html파일과 admin.js파일을 수정하였다. html, js파일 해석이 너무너무 어려웠다. ㅠㅠ.
axios.request({
method: 'post',
url: '/product',
data: {
name: product.name,
price: product.price,
image: product.image
}
axios.request({
method: 'put',
url: `/product/${id}`,
data: {
id: id,
name: product.name,
price: product.price,
image: product.image
}
axios.request({
method: 'delete',
url: `/product/${id}`
이렇게 수정함으로써 각각 create시에 요청에 대해 uri와 반환 data를 설정하였다. js에서 백틱을 사용하는 것도 처음알았고 너무 어려운 것 이라고 알게 되었다 . .
궁금한 것
DTO 변환
이번 미션에서 Controller → Service → Dao의 구조로 진행하였다. 서비스에서 ProductMapper를 통해 DTO와 Entity 변환, DTO와 Domain간 변환 을 진행했다. 진행하다 보니 복잡함이 느껴졌고 entity를 도메인 객체로 사용하면 되지 않을까 라는 생각이 들었다.
Entity를 도메인으로 두고 사용해도 충분하다고 생각합니다. 다만, 어플리케이션 코드가 복잡해지고, 도메인 규칙들이 굉장히 많고, 테이블 변경 가능성이 높아짐에 따라 Entity와 Domain은 "필요에 의해" 분리될 수 있다고 생각해요. 오션의 기준이 있다면 그 기준을 진행하는 것이 좋을 것 같습니다!
내 대답
지금은 크게 도메인의 비즈니스 로직이 없기에 entity를 도메인으로 두어도 되지만 비즈니스 로직이 생긴다면 domain을 통해 검증을 처리하고 entity로 검증된 값만 변환시켜야 된다고 생각합니다. 이번 미션에서는 그래서 entity를 도메인으로 두고 사용해도 되겠지만 현재 domain에서 검증로직이 있어서 domain을 사용하였습니다.
그럼 결국엔 service에서 받은 DTO를 domain을 통해 검증 및 비즈니스 로직을 수행하고 그 값을 영속성 layer로 전송하기 위해 (서비스-영속성계층 dto)entity로 변환하여 보내주게 된다고 생각하빈다.
Controller 분리
현재는 컨트롤러에 Rest Api, View 렌더링 기능이 있습니다. 현재는 하나의 컨트롤러에서 진행하는데 이를 분리하는 것이 좋을지 궁금합니다.
@controller 와 @RestController 의 차이가 어떤걸까요? 이를 인지하고 오션의 기준대로 분리해서 적용하면 될 것 같아요!
TEST
여기서 포인트는 Controller테스트의 범위를 어떻게 결정해야 하냐 인데요.
만약 비즈니스 로직을 mocking 하고 엔드포인트 요청과 응답에 대한 테스트만 하고싶으시다면, Service 를 mocking 하시고, 예상한 status code가 잘 응답되는지, 요청이 잘못되었을때 예상한 응답이 나오는지 등을 테스트 하셔야합니다.
반대로 전체 플로우를 테스트하는 통합테스트를 하시려면, dao에 데이터를 세팅하고 Get테스트를 하여 예상한결과가 나오는지, Post테스트 수행 후 실제 dao에 데이터가 저장되었는지 검증하셔야합니다.
Test에서 의존성 주입
생성자 주입으로 의존성을 주입했다. 프로덕션 코드에서 그래왔듯이 ..
필드에 붙여도 되는 내 생각은
프로덕션 코드에서는 필드 주입이 변경이 어려워 테스트하기 어렵고, 스프링이 아니면 외부에서 주입할 방법이 없다는게 문제로 알고 있는데 @SpringBootTest에서는 변경될 필요가 없고, CartServiceTest 객체를 생성할 필요가 없으므로 조금 더 편한 필드 주입을 사용했습니다. 다음과 같다.
네 맞습니다. 말씀해주신 기준이 정확해요. (그리고 테스트 코드에는 보통 생성자를 쓰지 않아서 어색한것도 한몫하는것같네요
😅)
코드 리뷰
endPoint가 Restful한지 ?
ResponsEntity.ok 면 의미없는 null값이 response되진 않는지 ?
Mapper사용 한다면 매 서비스 메소드별 매핑 로직이 추가될 것.
transactional readOnly 검토
Dto는 엔드포인트별 정의
나가며
스프링 재미있지만 어렵다. 나도 잘하고 싶다.....
'우아한테크코스' 카테고리의 다른 글
[우아한테크코스 5기] 지하철 1단계 학습로그 (1) | 2023.05.21 |
---|---|
[우아한테크코스 5기] 장바구니 2단계 학습 로그 (1) | 2023.05.07 |
[우아한테크코스 5기] 웹 자동차 경주 2단계 학습 로그 (1) | 2023.04.23 |
[우아한테크코스 5기] 웹 자동차 경주 1단계 학습 로그 (1) | 2023.04.23 |
[우아한테크코스 5기] 레벨1 레벨인터뷰 회고 (0) | 2023.04.06 |