티스토리 뷰
우아한 테크코스) Lv2 - 2주차 [블로그 - Spring Data JPA/회원 관련 기능 구현] 미션 후기, 코드리뷰
os94 2019. 9. 13. 18:26Lv2 - 2주차 미션 : Spring Data JPA/회원 관련 기능 구현
https://github.com/woowacourse/jwp-blog
학습목표
- Spring Data JPA 통해 데이터를 관리하는 경험을 한다.
미션
- 회원 등록/조회기능 구현하기
- 회원 로그인 기능 구현하기
- 회원정보 수정/탈퇴 기능 구현하기
- (adv) 페이징 기능 구현하기
- (adv) interceptor를 이용하여 로그인 기능 구현하기
체크리스트
- 모든 요청에 대한 Acceptance Test를 구현했는가
- HTML 중복 제거하였는가
- 테스트의 중복을 제거하였는가
- URL 컨벤션을 지키며 구현했는가
- 회원가입/수정 및 로그인/로그아웃 기능이 잘 동작하는가?
- 회원가입시 회원가입 유효성을 잘 확인하는가?
- 유저 정보 수정 / 회원 탈퇴 시 본인 확인을 하는가?
- 등록 실패 / 로그인 실패 시 에러 메시지가 잘 노출 되는가?
새롭게 알게된 것
- ORM과 JPA 그 전체적인 컨셉 (이부분의 강의자료가 무척 좋았음)
- Spring Data JPA
- H2 DB
- 에러 처리
- Cookie와 Session의 개념
- Logging
- Test
- interceptor (extends HandlerInterceptorAdapter)
- Exception Handler, Controller Advice
느낀점
- JPA를 사용하니 짱 편했다. 다만 동시에 그 위험성도 인지. 사용하긴 쉽지만 그만큼 추상화되고 감춰지는 만큼, 남용을 자제해야한다. 쿼리가 어떻게 왔다갔다 하는지 직접 확인하는 것이 좋은 습관.
- 이번주차엔 중요한 개념들을 많이 배운것 같다.
- 쿠키와 세션 개념을 적용하며, 이를 이용한 테스트 방식 터득 (이후의 주차에 WebTestClient에서 JSESSIONID를 더욱 간단하게 추출, 설정하는 방법을 알게 됨)
- 인텔리제이 콘솔에서 더욱 다양한 정보를 볼 수 있게 되었다. JPA을 거치는 쿼리문들과 HTTP header/body 로그들, 그리고 Logging Library의 다양한 기능들.
- 감이 안오던 테스트 방식과 관련해, 큰 그림에서의 몇가지 방법과 키워드를 듣게 됨
- 영속성 컨텍스트 - 무거운 개념이라 나중에 시간 생길때 제대로 공부해봐야할것같음
- mypage-edit에서 sns까지 업뎃하려다, JPA에서의 테이블 조인 어려워 포기. 이후 주차에 관계매핑을 학습하고 방법을 알게 되었다
- js 함수를 연결하고 트리거하는 기본적인 방법들을 숙달
내 코드, 피드백 관련
프론트 피드백
-
백과 같이 똑같이 신경써주자
- html 파일명 일관되게 : -던 _던 camelCase던
- 함수, 변수 등 네이밍도 일관되게
- 디렉토리 분리
-
fragments와 같이 폴더를 분리했다면, 파일마다 common같은 prefix 안붙여도 될것같다
-
if/unless로 코드 중복시키지말고, ? : 삼항연산자로 줄일수있다. 백처럼 꺼리지 않아도 될듯
-
id값은 중복되지않도록. if/unless로 둘중하나만 렌더링되더라도 가급적 지양하자
그외
-
session.removeattribute vs session.invalidate
-
검증과 에러처리
- 프론트에서 form을 입력받는 경우, 당연히 프론트에서도 1차적으로 체크해준다
- 서버에선 기본적으로, catch한 에러를 Model(이나 이후엔 Ajax)로 담아 프론트에 돌려준다
- 이때 controller에서 spring validation과 Thymeleaf를 통해 Annotation을 붙여 간단히 검증할수있었다(컨트롤러 메소드 인자엔
@Valid
). 다만 이 방식의 경우, 서버에서 잡은Errors
나BindingResult
클래스를 원하는대로 커스텀해서 자유롭게 다루는게 쉽지않았고, 결국 프론트에서 docs가 시키는대로 타임리프로 잡아야했다. 이때 다음과 같이 get에서 빼먹는 실수 발생
-
회원가입창에서 회원가입 시도시 검증을 위해 위에서 언급한 `@Valid`와 `BindingResult`를 이용한 방식을 사용하는데, 이때 같은 페이지지만 맨처음 GET을 통해 진입할때도 `UserRequestDto`를 사용하진않지만 인자에서 받긴해야한다. 프론트코드에선 항상 값을 기다리고 있으므로. 이부분을 깜빡하고 오래 삽질함
-
Entity에서 `@Id` import할때 다른걸로 잘못해서 한참 삽질 (뭔지 확인 잘하자...)
-
시간이 아까웠던 삽질, gradle의 dependency나 js의 cdn script 등 추가하는걸 빼먹는것. docs 잘보자, 당연한게 아닐수도
-
Entity에서 default constructor의 필요성에 대해
-
페어와 raw한 방법으로 Ajax와 ResponseEntity를 처음으로 접하고 써봄(signup.html). 이후의 주차에 다시 제대로 배우게 됨
스프링 어노테이션들, 특히 @Transactional 유무에 따라 기능이 아예 안되기도하므로 정확한 역할 알아보자-
Controller 테스트를 @Autowired UserRepository없이 하고싶었으나 실패 (delete의 url에 id가 포함되어 힘들었음)
-
비모가 한것처럼 Validator를 사용해 dto 테스트를 하면 더 좋았을 것
-
서비스 테스트 하지못함 : MockMvc를 공부해보자
- MockMvc는 실제 http요청이 가는건 아님. vs WebTestClient와의 차이, 상황에 따라 적절한걸로
-
`@RequestMapping`을 사용하며, 아래와 같은 삽질
-
validation을 dto에서 하는게 나을지 or domain 클래스에서 하는게 나을지 고민해볼수있었다. 이렇게 전체적인 흐름에서 적절한 validation의 위치 & validation 방법에 관한 고민은 이후에도 계속 이어졌다. github/discussion 참고
-
Service를 무조건 프론트와 매핑시키기보다 적절히 나누는것도 좋은 시도였다. -> 이후의 주차엔, 반대로 무조건적으로 서비스를 나누는 부분에 대해서도 피드백을 받게 됨. 그때그때 상황에 맞게 적절히.
- 코딩하며 설계를 고려하자
- 상수처리!
- DB와 관련된 테스트가 어려웠다. -> 미션 진행중엔 기능구현에 급급하느라 테스트를 전반적으로 신경쓰지 못했는데, 이번 레벨이 마무리될쯤엔 전체적인 테스트 방식에 조금은 감을 찾게 되었다. + 토비스프링의 트랜잭션 챕터를 함께 읽으며
'우아한 테크코스' 카테고리의 다른 글
우아한 테크코스) Lv2 - 4주차 [블로그 - 비동기 통신&API / 댓글 추가 기능 구현] 미션 후기, 코드리뷰 (0) | 2019.09.16 |
---|---|
우아한 테크코스) Lv2 - 3주차 [블로그 - 빌드&배포 구성 / 댓글 관련 기능 구현] 미션 후기, 코드리뷰 (0) | 2019.09.16 |
우아한 테크코스) Lv2 - 1주차 [블로그 - Spring Boot/게시글 관련 기능 구현] 미션 후기, 코드리뷰 (0) | 2019.09.13 |
우아한 테크코스) Lv1 - 6~8주차 [Chess] 미션 후기, 코드리뷰 (0) | 2019.09.13 |
우아한 테크코스) Lv1 - 4~6주차 [Lotto] 미션 후기, 코드리뷰 (0) | 2019.09.13 |
- Total
- Today
- Yesterday
- 개발자
- 해외여행
- javascript
- JPA
- socket
- webhacking.kr
- FRAGMENT
- 프로그래머스
- reversing
- 리버싱
- Android
- git
- queue
- Vo
- Stack
- dfs
- 우아한 테크코스
- Data Structure
- Java
- Android Studio
- sort
- 웹해킹
- C
- Algorithm
- brute-force
- OneToMany
- bfs
- mysql
- 회고
- graph
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |