들어가며
GitHub 저장소
구현 기능들
궁금한 것
코드 리뷰
후기
📆 기간 : 2023.04.11 ~ 2023.04.13
들어가며
레벨 2 들어와서 처음 하게된 미션이라 떨렸다. 이번에는 레벨1에 구현한 자동차 경주 코드를 웹으로 구현하는 과정이였다.
이번 미션은 민트와 함께 하였다. 같은학교 같은학번 친구였기에 친했다. 그래서 정말 재미있게 할 수 있었다. 서로 스프링 프레임워크에 대해 학습하면서 미션을 진행하였다. 친한 사람과 하게 되니 재미가 두배였다.
같이 미션 뿐 아니라 학습테스트 도 진행하면서 하였다. 여럿이서 학습을 하니 이해도 잘 갔고 잘 진행되었던 것 같다. 만족스러웠다.
GitHub 저장소
구현 기능 목록
웹 요청 / 응답 구현
이번 미션에서는 요청과 응답이 있었다.
Post 와 Get한개씩 구현하였다. 처음에는 어떻게 데이터를 받고 어떻게 데이터를 전송하고 가공해야되는지에 대한 의문이 많았다.
레이어드 계층으로 분리하였고 DB와 연동을 하면서 진행을 하였다.
처음에는 의존성이 무엇인가 부터 시작해서 레이어드 계층 ? 이 뭐지 Dto는 어떻게 나누지 에 대한 의문들이 많았다. 그리고 DB와 연동되는 계층은 어떻게 다뤄야하고 jdbc를 어떻게 사용하여야 하는지에 대한 의문이 정말 많았다. 그래서 이번 미션에서는 학습에 초점을 두고 진행하고자 하였다.
Request이다.
POST /plays HTTP/1.1
content-type: application/json; charset=UTF-8
host: localhost:8080
{
"names": "오션, 민트",
"count": 10
}
Response이다.
HTTP/1.1 200
Content-Type: application/json
{
"winners": "오션",
"racingCars": [
{
"name": "오션",
"position": 9
},
{
"name": "민트",
"position": 7
},
]
}
DB 연동
DB는 h2를 사용하였다. 인메모리 db를 사용하였다.
db와 연결되는 계층으로 dao를 만들었고 사용하였다.
다형성을 위해서 dao인터페이스를 만들어 구현체를 구현하는 방식을 진행하였다.
궁금한 것
서비스에서 로직은 어떤 방식으로 구현하여야 할 까?
나는 자동차 경주 로직 + DB저장 이 한 메소드에서 실행 되는 것은 한 메소드가 많은 역할을 갖는게 아닌가? 라는 생각을 하였다. 파즈는 괜찮아보인다고 말하였다. 그 후 내가 생각한 것은 서비스는 도메인 로직들을 사용하는 곳이기에 비즈니스 로직 여러개를 조합하여 사용할 수 밖에 없다는 것이다.
Repository와 Dao의 차이는 무엇일까 ?
나는 dao는 데이터에 접근하도록 db접근 로직을 모아놓은 객체라고 생각하고 repository는 도메인 객체를 관리?저장?하는 저장소라고 생각하였다. 그래서 당연히 dao를 사용하였다.
하지만 어노테이션도 @Repository이고 주변 크루들도 레포지토리라고 많이 칭하길래 궁금하였다.
파즈는 repository는 저장소, 일급컬렉션으로 생각한다고 한다.
CarRepository {
Car findWinnerCar(int winnerId) {
carDao.findById(winnerId)
}
Car findCarByName(String name) {
carDao.findByName(name);
}
}
이런 방식으로 사용될 것이라고 하였다. 하지만 이론에 잠식될 필요가 없다고 조언해주었다. 개발자가 편리하라고 한 것이기에 내가 이렇게 생각한다면 이렇게 사용하면 될 것이라 하였기 때문이다.
결론은 레포지토리에서 dao를 호출한다고 보았다.
레포지토리는 도메인과 조금 더 맞닿은 개념이고, db테이블과 매칭되는 개념은 dao에 가깝다. dao가 실제 영속화 시키는 방법을 고민한다. 그리고 repository가 dao를 의존하게 되는 구조이다.
자동차 도메인은 어떻게 영속화 되는지보다는 영속화 되는것 자체(repository)를 사용할 것이고 실제 영속화 시키는 방법은 그래서 dao가 실행해주는 것이다.
DTO와 Domain간 변환은 어디서 이루어 지는 것이 좋은가 ?
controller {
public ResponseDto methodA(@RequestBody Dto dto) {
A a = aService.findByInfo(dto.getInfo());
B b = bService.findByAId(a.getId())
return b의 정보가 담긴 responseDto
}
}
이런 코드가 있을 경우에 a service와 b service는 각각 반환하는 것이 dto가 아니다.
이럴 경우 어디서 dto를 조립하는 것이 좋은가 ?
1. 둘 다 domain을 반환해서 controller에서 조립할 경우
2. a는 도메인 b는 dto를 반환할 경우
2번은 어떤 서비스는 dto를 반환하고 어떤 서비스는 domain을 반환하는 것이 일관성을 해친다.
Response할 Dto는 우리가 레벨1에서의 View라고 생각해도 된다. View는 변경이 잦는다. 그래서 깊은 layer로 가지고 가는 것은 좋지 않다. 사이드 이펙트가 많기 때문이다. 그래서 service에서 반환하는 타입은 controller에서 response dto형태로 주진 않는다. 이럴경우 dto조립 코드가 많아질 수 있는데 파즈의 회사에서는 mapper클래스를 따로 두어 사용한다고 한다..
코드 리뷰
@Valid를 이용하여 검증을 하면 좋다.
DTO 이름 더 명확하게 하자.
ResponseEntity를 사용해보자.
dao 에서 여러번의 insert문을 사용하기 보다 한번에 처리되기 위해 batchUpdate를 사용해보자.
나가며
스프링 첫 미션이였다. 어려웠지만 재미있었다. 자바보다는 재미있는 것 같다. 이를 보면서 내가 지금까지 구현했던 스프링은 아무생각없이 작성했구나 라고 느끼게 되었다 .. 열심히 공부해서 다음 미션에서는 이해하면서 코드작성을 하고 싶다.
'우아한테크코스' 카테고리의 다른 글
[우아한테크코스 5기] 장바구니 1단계 학습 (2) | 2023.04.30 |
---|---|
[우아한테크코스 5기] 웹 자동차 경주 2단계 학습 로그 (1) | 2023.04.23 |
[우아한테크코스 5기] 레벨1 레벨인터뷰 회고 (0) | 2023.04.06 |
[우아한테크코스 5기] 체스 2단계 학습 로그 (0) | 2023.04.02 |
[우아한 테크코스 5기] 체스 1단계 학습 로그 (0) | 2023.03.26 |