그로스로그 앱 설계를 진행하면서 찾아본 내용과 고수님들에게 얻은 피같은 조언을 기억나는대로 정리해야겠다
DB 테이블 설계
- 키는 int(인덱스) 로 해야 확장성이 좋음
- 인덱스를 사용하면 쿼리 성능이 좋아짐 -> 인덱싱이 가능해짐
- 사용자와 관련된 행동(출석, 입금 등) 모든 정보를 로그식으로 남기면 좋음
JWT 인증 방식
- accessToken 으로 Spring boot 에서 권한을 설정함
- filter 단에서 accessToken 기반으로 권한을 설정하지 않으면 인증이 안됨
- refreshToken 을 관리하는 방법은 서버 저장 or 클라이언트 저장이 있음
- refreshToken 은 accessToken 이 만료되었을 경우, 새로운 accessToken 을 발급하기 위함
- 서버측 저장은 서버 단에서 Redis or DB 를 사용해 사용자별 refreshToken 을 저장
- 클라이언트측 저장은 서버에서 refreshToken이 발급되면 Cookie 로 반환하여, Cookie 에 refreshToken 이 저장되도록 함
DTO 변환시점
- Repository 에서 DB 데이터를 조회하고 받은 Entity 를 어디서 DTO 로 변환해야할지 고민 했다.
- QueryDSL 을 사용하는 경우, Projection 을 사용하여 지정한 DTO 로 쿼리와 함께 변환이 가능하다.
- QueryDSL이 아니더라도 @Query 에서 특정 DTO에 생성자를 이용하여 바로 DTO 로 반환이 가능함
- 별도 Mapper 클래스를 생성 or DTO 에 toENTITY, formENTITY 메서드를 구현하여 변환
- Repository 에서 변환을 하는 경우, 네트워크 비용이 감소하고, 대용량 데이터를 조회할 때 성능에 이점이있다.
- 단, Repository 에서 변환 시 SRP가 위배됨 -> Repository는 "데이터베이스 액세스" 에 중점을 두어야 하는 데, 변환의 역할까지 맡기 때문이다.
- 또한 DTO에 변경이 Repository 까지 영향을 주어, 설계 원칙에 위배될 수 있음
- UseCase(서비스) 에서 변환하는 경우, 비즈니스 로직을 명확하게 분리 가능, Repository 는 데이터베이스와 상호작용에 집중 가능(SRP 원칙 준수), DTO 변경이 Repository 에 영향 없음
- 단, Repository 에서 변환하는 것보다 성능이 떨어짐, 별도 변환 작업이 들어가며, 코드를 더 많이 짜야 함
그 외 느낀점
- 설계가 무척 중요하다고 생각이 들었음, 테이블 설계가 잘 이루어지면 이외에 크리티컬한 수정 사항이 줄어드는 것 같음
- ERD 나 흐름도는 설계 사항을 공유하는 데 큰 역할을 함 -> 사실 작성을 잘 안하고 일을 해왔기 때문에 많이 부족한 부분이지만 앞으로 설계시에 작성하는 습관을 가져야겠음
- git 은 좋음 -> branch 가 폴더를 복사하는 개념이 아님, 스냅샷 느낌으로 특정 커밋에 대한 포인터를 연결하는 방식으로 분기가 너무 자유로움, 다른 사람 수정에 방해받을 일이 없음
- 의존성을 분리하는 설계는 무척 어려움, 가장 어려운 건 초짜가 이렇게 설계를 했을 때 뭐가 좋을 것이라는 것을 한번에 알 수가 없음, 많은 경험이 필요함
평소 시간에 쫒기기만 하면서 생각없는 기능을 막 만들어냈는데, 이렇게 사이드 프로젝트를 진행하면서 그동안 생각하지 못했던 부분을 여러 고수님들께 배우니 색다른 느낌이 들었다.
물론 일을 하면서 진행하기에 시간이 많이 부족한 부분은 있지만, 새로운 아키텍처를 경험하면서 배우는 건 큰 경험이 될 것 같다.