New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[4기 김별] Shorten URL 과제 PR입니다 #52
base: byeolhaha
Are you sure you want to change the base?
Conversation
- 2차 캐시 이용하여 Origin Url 찾기
|
||
@Scheduled(fixedRate = 3600000) | ||
public void evictUrlsCache() { | ||
log.info("캐시는 1시간 뒤에 지워집니다."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
불필요한 로그메시지 인거 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사실 테스트를 통해서 검증했어야 했는데
@Scheduled
에 대한 테스트 방법을 발견하게 되어 추가하도록 하겠습니다.
중요하지 않고 불필요한 로그 메세지여서 삭제하도록 하겠습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 프로젝트에서 캐시는 불필요한것 같아요 ㅎ
|
||
private final CacheManager cacheManager; | ||
|
||
@Autowired |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ㅋㅋ 태그걸때 꼭 그걸로 이름지은 놈들 있어서 조심하셔유 ㅋㅋ @Autowired
@ExceptionHandler(ExistedOriginUrlException.class) | ||
protected ResponseEntity<ErrorResponse> handleExistedOriginUrlException(ExistedOriginUrlException e) { | ||
log.warn("Handle ExistedOriginUrlException", e); | ||
final ErrorResponse response = ErrorResponse.of(e.getErrorCode(), e.getMessage()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
왜 지역변수에 final을 사용하셨어요?
파라미터도 final을 붙여주는것이 좋아요.
메서드 내에서 해당 파라미터의 값을 변경할 수 없게 되어 파라미터 값이 예기치 않게 변경되는 것을 방지할수 있거든요
물론 코딩스타일이나 팀의 코딩 컨벤션에 따라 다르기도 해요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
메서드 내에서 변할 수 없다는 것을 내포하고, 실제로 변경에 대한 위험을 방지하기 위해서 넣게 되었습니다.
파라미터에 final도 좋은 방법인 거 같아
다음 프로젝트를 진행할 때 팀원들과 이야기해 코딩 컨벤션을 정하도록 할게요 💡
*/ | ||
@ExceptionHandler(MethodArgumentNotValidException.class) | ||
protected ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { | ||
log.warn("Handle MethodArgumentNotValidException", e.getMessage()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warn으로 찍은 이유가 궁금해요!
final ErrorResponse response = ErrorResponse.of(INTERNAL_SERVER_ERROR, e.getMessage()); | ||
return ResponseEntity | ||
.status(HttpStatus.INTERNAL_SERVER_ERROR) | ||
.body(response); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final ErrorResponse response = ErrorResponse.of(INTERNAL_SERVER_ERROR, e.getMessage()); | |
return ResponseEntity | |
.status(HttpStatus.INTERNAL_SERVER_ERROR) | |
.body(response); | |
} | |
final ErrorResponse response = ErrorResponse.of(INTERNAL_SERVER_ERROR, e.getMessage()); | |
return ResponseEntity | |
.status(HttpStatus.INTERNAL_SERVER_ERROR) | |
.body(response); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개행에 의미를 부여해서 가독성을 높이도록 하겠습니다 🔦
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.getMessage도 좋지만 Throwable을 파라미터로 받는것도 괜찮을듯 합니다ㅎ
shortUrlService.creatShortUrl(naverUrlToSave.getOriginUrl(), "BASE62"); | ||
savedNaverUrl = shortUrlRepository.findByOriginUrl(naverUrlToSave.getOriginUrl()).get(); | ||
|
||
for (int i = 0; i < 20; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
왜 20번인지 의도가 궁금해져요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
10번 이상일 때 캐시에 저장된 객체를 가져오는가를 테스트하기 위함이었지만
실제로 테스트를 보는 사람은 저 20의 의미를 알기 어렵다고 생각합니다.
그리고 저 20이라는 숫자는 바뀔 수 있는 수이기 때문에
항상 같은 테스트 결과가 나오도록 고치겠습니다.
|
||
private Optional<Urls> getCacheUrl(String shortUrl) { | ||
return Optional.ofNullable(cacheManager.getCache("urls")).map(c -> c.get(shortUrl, Urls.class)); | ||
} | ||
|
||
@Test | ||
@DisplayName("요청 횟수가 정해진 limit 수를 넘어가면 2차 캐시에 저장하여 다음 요청에서 2차 캐시에 있는 origin url을 반환한다.") | ||
void getUrlByShortUrl_overLimitedBoundCount_returnCache() { | ||
//when | ||
Urls urlByShortUrl = shortUrlRepository.getUrlByShortUrl(savedNaverUrl.getShortUrl()); | ||
|
||
//then | ||
assertThat(urlByShortUrl).isEqualTo(getCacheUrl(savedNaverUrl.getShortUrl()).get()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
테스트가 위로 오면 좋을것 같아요.
class ShortUrlServiceImplTest { | ||
|
||
private final Urls NAVERURL = Fixtures.naverUrlInOriginUrl(); | ||
; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수염 제거하도록 하겠습니다. 🧔♀️
shortUrlService.creatShortUrl(NAVERURL.getOriginUrl(), STRATEGY_TYPE); | ||
|
||
//when_then | ||
assertThrows(ExistedOriginUrlException.class, () -> shortUrlService.creatShortUrl(NAVERURL.getOriginUrl(), STRATEGY_TYPE)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertThrows(ExistedOriginUrlException.class, () -> shortUrlService.creatShortUrl(NAVERURL.getOriginUrl(), STRATEGY_TYPE)); | |
assertThrows(ExistedOriginUrlException.class, | |
() -> shortUrlService.creatShortUrl(NAVERURL.getOriginUrl(), STRATEGY_TYPE)); |
저는 너무 길어지면 이렇게 쓰기도 해요.
|
||
private final Urls NAVERURL = Fixtures.naverUrlInOriginUrl(); | ||
; | ||
private final String STRATEGY_TYPE = "BASE62"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
중복 발견! 오타나면 영문도 모르겠어요. StragteType을 어떻게 관리하면 좋을까요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enum으로 관리하도록 하겠습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
캐시에다가 shortenurl을 저장하는 부분을 제외하고는 괜찮은 것 같습니다. 영수님이 이미 좋은 리뷰를 많이 주셔서 첨언할 부분은 cache 의 hit정도가 이 프로젝트의 그 기능이 적절한지에 대해서 고민해보면 좋을듯요. sql이나 jpa에도 캐시를 활용하는 부분이 있다는 점을 생각해보면 좋을 듯해요.
|
||
private final CacheManager cacheManager; | ||
|
||
@Autowired |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ㅋㅋ 태그걸때 꼭 그걸로 이름지은 놈들 있어서 조심하셔유 ㅋㅋ @Autowired
|
||
@Scheduled(fixedRate = 3600000) | ||
public void evictUrlsCache() { | ||
log.info("캐시는 1시간 뒤에 지워집니다."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 프로젝트에서 캐시는 불필요한것 같아요 ㅎ
final ErrorResponse response = ErrorResponse.of(INTERNAL_SERVER_ERROR, e.getMessage()); | ||
return ResponseEntity | ||
.status(HttpStatus.INTERNAL_SERVER_ERROR) | ||
.body(response); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.getMessage도 좋지만 Throwable을 파라미터로 받는것도 괜찮을듯 합니다ㅎ
@Column | ||
@Embedded | ||
private ShortUrl shortUrl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unique 조건 생략된것 같네요. 비즈니스적 insert 동시성을 해결하는 이슈로 db의 unique를 활용할 수 있습니다.
|
||
public interface ShortUrlRepository { | ||
|
||
void isExistedOriginUrl(String originUrl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
프로젝트 전반적으로 is로 시작하는 void가 많이보이는데 is는 플래그를 상징하는 키워드임. getXX랑 같이 뭔가 boolean을 리턴할것같은 느낌을 주니 반드시 고치세요.
|
||
public interface ShortUrlRepository { | ||
|
||
void isExistedOriginUrl(String originUrl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
코드를 고치라는 부분이 아니라 이렇게 작성되지 않도록 고쳐보세요. 재발되면 안될것 같아요.
📌 과제 설명
👩💻 요구 사항과 구현 내용
✅ PR 포인트
@Scheduled
를 이용해서 비우는 작업을 했습니다.1시간
의 의미는 실제 요청에 대한 데이터가 있어야 올바른 예측값이 나올 거 같습니다.https://
나http://
로 시작하는지 확인하는 작업을 했습니다.