티스토리 뷰

Lv2 - 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). 다만 이 방식의 경우, 서버에서 잡은 ErrorsBindingResult 클래스를 원하는대로 커스텀해서 자유롭게 다루는게 쉽지않았고, 결국 프론트에서 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와 관련된 테스트가 어려웠다. -> 미션 진행중엔 기능구현에 급급하느라 테스트를 전반적으로 신경쓰지 못했는데, 이번 레벨이 마무리될쯤엔 전체적인 테스트 방식에 조금은 감을 찾게 되었다. + 토비스프링의 트랜잭션 챕터를 함께 읽으며
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함