프로젝트 배경
지금까지 공부한 것들을 이용해서 프로젝트를 만들고 싶었다.
무슨 주제를 할까 생각을 하다보니 나의 취미 중 하나인 노래부르기를 이용해서 프로젝트를 할까? 라는 생각을 했었다.
그러면서 누군가가 내 노래를 듣고 평가를 해주면 좋겠다는 생각을 했다.
그렇게 SingingStar라는 프로젝트를 시작하게 되었다.
프로젝트 설계
처음에 프로젝트 설계할 때 부터 문제가 느껴졌다.
erd를 설계하는데 어떤식으로 설계하는 지 모르겠고 어디서부터 시작해야할 지도 모르겠었다.
그래서 많은 공부를 했고 많은 레퍼런스를 참고해서 만들게 되었다.
아직 erd에 대해서 더 공부를 해야겠지만 이것을 만들면서 erd의 중요성을 알게 되었다.
그리고 기초 기반을 더 잡기 위해서 figma를 이용해서 View를 미리 작업을 해보았다.
figma로 처음 만들어봐서 어려웠다 ㅠ...
대충 처음 만든 View하고 얼추 비슷하게 나와서 기분은 좋당..
api를 설계하려고 했는데 확실히 제대로 된 프로젝트를 만들려고 하니까 너무 어려웠다..ㅠㅠ... 더 공부해야겠당..
설계파트는 진짜 형편이 없던 것 같다. 더 공부해서 다음번에는 제대로 설계파트부터 확실히 잡고 가고싶다.
프로젝트 구현
제일 중점으로 둔 것은 하나를 끝까지 만드는 것이였다.
배포까지 하는 게 목표였다.
로그인 로그아웃
일단 처음 만들 기능은 Spring Security를 사용해서 로그인 로그아웃을 만드는 것이였다.
사실 Spring Security에서 기본으로 제공하는 로그인도 있어서 어렵지는 않았다.
하지만 그 세부기능은 사용해본 적이 없어서 공부를 많이 하게되었다.
특히 로그인 되어있는 사용자인지 체크하는 부분이 제공되고 Principal로 사용자 정보를 가지고 올 수 있는 게 큰 메리트 였던 것 같다.
하지만 Spring Security를 이용해서 OAuth2 를 이용하는 게 너무 어려워서 다음번에는 Session이나 jwt를 이용해서 로그인 로그아웃을 구현해서 OAuth2 를 이용해서 다른 포맷으로 로그인하는 걸 꼭 구현하고 싶다.
회원가입
회원가입 부분은 User라는 도메인을 만든 후 Service파트에서 회원가입폼에서 Post를 받아서 DB에 저장하는 식으로 했다.
비밀번호는 BindingResult를 이용해서 암호화를 했다. 하지만 이 부분을 쓰니까 비밀번호 찾는 부분은 어떻게 구현할까 고민이 많았는데 다행히 여기서 제공하는 메서드중인 디코딩이라는 기능이 있어서 비교가 가능했다. 그래서 회원가입 부분은 크게 어렵지 않게 구현할 수 있었다.
이메일인증 부분
게시판
게시판 만들기는 사실 어렵지 않았다. 그동안 공부한 것으로 충분히 만들 수 있었다. 여기서 어려웠 던 부분은 어떻게 여러카테고리를 이을 수 있을까? 라는 생각 때문이였다.
여기서 오래 걸린듯..
그냥 단순하게 댓글처럼 카테고리도 따로 매핑을 해서 구현을 하게 되었다.
그리고 제일 중요하게 생각한 기능은 유튜브 영상을 넣을 수 있는 기능이였다.
이 부분도 DB에 video라는 부분으로 저장하면 될 것 같다고 생각은 했는데 View에서 어떻게 처리를 해야할 지 고민이 많았다. 공부를 해보니 Thymeleaf에서 th:utext라는 것을 쓰면 그대로 html으로 인식이 되어서 그 부분을 처리 할 수 있어서 구현을 하게 되었다.
사실 View 부분을 만드는게 오래 걸렸지... 기능 구현하는 부분에서 엄청 오래 걸리진 않은 것 같다.
하지만 확실한 것은 클린코딩이 안된다는 것이고 <클린코드>라는 책을 구매해서 깨끗하게 코딩을 하고 싶당..
댓글
댓글 파트는 Comment라는 도메인을 만든 후 DB에 저장해서 View에서 불러는 방식을 이용해서 크게 어려운 부분은 없었다. 그리고 cascade = CascadeType.REMOVE 이 부분을 넣어서 부모인 게시글이 삭제되면 게시글에 매핑된 모든 댓글이 삭제되게 만든 부분이 특징인 것 같다.
추천
좀 어려웠던 부분은 추천파트였다.
ManyToMany라는 것도 처음 써 보는 것이였고 어떤식으로 매핑을 해야할 지 도 감이 안 왔다.
여기서 공부해보니 Set를 이용하면 괜찮을 것 같았다.
add, contain, remove기능을 제공하고 있기 때문에 관리하기도 쉬울 것 같았다.
contain을 사용하게 된 이유는 이 유저가 추천을 했는지 안했는 지 파악하기 위해서 사용하게 되었고 만약 추천을 했으면 remove하고 안했으면 add하는 방식으로 Service 파트를 만들었다.
View에서는 set의 사이즈를 불러와서 추천이 몇개 눌렸는 지 파악하게 만들었다.
조회수
조회수 부분이 사실 너무 아쉽다. 쿠키를 이용해서 만들고 싶다는 생각이 너무 컸는데 지금 당장 리팩토링이 너무 여러워서... @Modifying 과 @Query 파트로 직접 쿼리를 짜서 id가 입력되면 ViewCount가 하나씩 올라오는 방식을 쓰게 되었다.
하지만 중복 조회수가 올라가서 너무 아쉽다.. 다음 프로젝트나 버젼 업을 하게 된다면 싹 다 갈아엎고 싶다 ㅠ...
검색
jpa에서 특정 title이 주어지면 검색하는 방식을 사용하였다.
정렬
jpa로 직접 정렬을 내렸다.
실시간 순위
Index부분에 실시간 순위를 꼭 만들고 싶었다. 그래서 처음에는 List를 자르는 방식인 sublist방식을 이용했었는데 문제점이 배포를 하고나서는 데이터가 없기 때문에 index가 넘어간다고 오류가 뜨는 것이였다.. 그래서 고민해서 나온 방식이 Reposiotry안에서
findFirst5ByOrderByViewDesc()
을 이용해서 5개를 자를 수 있다는 것을 알게 되었다. 그래서 3부분을 다 이런식으로 구현했다. 하지만 더 좋은 방식이 있을 것이라고 생각을 하고있다. 그래서 이 부분도 꼭 리팩토링을 하면서 수정하고 싶다...
View 부분
뷰에서는 크게 신경쓴 것은 사용자가 인증되어있을 때 와 아닐 때를 구분하는 부분이였다. 예를 들면 Admin Role을 가지고 있으면 공지사항에 글쓰기가 가능하다던지 아니면 글쓴 본인이 아니면 게시글의 삭제나 수정이 불가능하게 만드는 기능을 만드는게 중요한 부분이였다. Thymeleaf와 Bootstrap을 많이 공부하게 되었다. 진짜 View부분은 너무 어려운 것 같다. 원하는 곳에 넣는 것도 힘들당... Frontend하시는 분을 존경하게 됐다..
아쉬운 점 및 공부할 부분
oauth2를 이용해서 로그인을 못 만든게 너무 아쉽다.. 이 부분을 꼭 공부해서 다음 버젼이나 다음 프로젝트 때는 꼭 써먹고싶다.