[인프런 워밍업 클럽] 세 번째 발자국

[인프런 워밍업 클럽] 세 번째 발자국

어떤게 기억에 남는가?

이번 3주차에서는 마지막 특강이 있었습니다. 백엔드 코스에서는 미니 프로젝트를 제출한 사람들 중 코드 리뷰를 신청한 사람들을 추첨하여 멘토인 태현님께 리뷰를 받는 형식이었습니다. 정말 감사하게도 저는 코드리뷰 대상자로 당첨되어서 첫 번째로 코드리뷰를 받을 수 있었습니다. 원래 특강 시간이 20시부터 21시까지 1시간만 진행될 예정이었으나 코드 리뷰 특성상 주어진 시간보다 길어져서 22시 50분 쯔음에 끝났습니다.
(특강이 끝날 때쯤 되니까 태현님 목소리가 시작할 때보다 많이 쉬어있어서 마음이 좋지 않았습니다..)

코드리뷰는 어땠나?

코드리뷰는 태현님께서 미니 프로젝트 기능 구현 요구사항대로 기능을 구현하고 그 코드에 대해서 리뷰를 받는 것이었습니다. 정말 운이 좋게도 저는 리뷰 첫 번째 순서에 당첨되어 리뷰를 받을 수 있었다.

대충 기억나는 것은 아래와 같습니다.

@RequestMapping("/api/teams")을 처럼 사용하는 것이 좋을까?

1. /api/teams/team 이라는 엔드포인트가 조금 어색한 것 같다

-> /api/team이 좀 더 괜찮지 않았을까?

2. 컨트롤러에서 등록만 하는 거라면 굳이 ResponseEntity나 객체 반환을 할 필요는 크게 없다.
상환에 따라서 Client가 POST에서 이런 응답을 주면 좋겠다라는 요청이 있다면 해도 된다.


3. Repository에서 중첩 쿼리는 절대 쓰지 않는다.
이는 대표적인 안티패턴이다. 그렇다면 중첩을 안 시키고 데이터를 SQL을 한 번에 가져오려면?
이때 쓸 수 있는 기능이 sql의 join + group by 같은 기능을 사용한다.
한방 쿼리를 쓰는 것은 좋은 방법이다.


4. 빌더를 바로 서비스에서 사용하기 보다는 DTO에서 toEntity() 메서드를 만들어서 객체를 만드는 것이 좋다.


5. Repository 쿼리에서 CASE 구문을 웬만해서는 사용하지 말자.


6. LocalDateTime.now()가 반복되길래 상수로 선언하고 사용했었는데 이는 LocalDateTime.now()가 서버가 구동되는 시점을
기록하고 상수에 할당하는 것이기 때문에 의도와 다르게 동작할 수 있다. 만약 현재 시간을 기입하고 싶다면 그냥 LocalDateTime.now()를 사용하자.


7. 객체간의 연관 관계는 최대한 맺어주지 않는 게 좋다. 라이프 사이클이 동일할 때만 연관관계를 맺어주자


8. (어려운 내용) 누군가 API 호출을 진짜 기가 막히게 동시에 2번 하게 되면?
현재 구현 상으로는 Attendance가 2개가 생긴다.  
스프링은 기본적으로 멀티 스레드 환경에서 구동한다.  

그렇다면 어떻게 막는가?  
Lock 3가지 (낙관적 락 / 비관적 락 / 유저 락)
또는 Unique Key로 막을 수 있다.

9. BaseEntity를 최대한 사용하자 예를 들면 최초 생성일, 마지막 수정일 같은 것을 꼭 상속 받아서 사용할 수 있도록 하자


10. soft delete를 생각하자.


11. @PathVariable 보다 @RequestBody 나 Http Query 사용을 지향하자 (사용 빈도 분석에 유리함)

제가 당장 고려할 수 있는 부분들을 중점적으로 기록하였고, 그 외의 기록들은 머리로 최대한 이해하려고 했습니다.

제 리뷰가 끝나고는 다른 참가자 분들의 코드 리뷰도 볼 수 있었습니다. 보면서 놀랐던 게 제가 고려하지 못한 부분이나 구현하지 못한 기능을 쉽게 구현하신 듯한 느낌을 받았을 때 많이 놀랐습니다. 이는 제가 앞으로 더 배워야 할 것들이 많음을 다시금 깨닫게 해주는 계기가 된 것 같습니다.

댓글을 작성해보세요.