Spring을 참 싫어하는 나로서는, Spring 으로 개발한다는 것이 좀 싫고 그렇다.
어떻게 보면 가장 익숙하게 쓸 수 있는데도, 한창 배울 시기에... 그 때의 트라우마가 남아서 꺼림칙할 때가 있다.
뭐, 개인적인 감상이고.
지금은 밥벌어 먹고 살려고 하는 중.
간단한 Tip 이지만, 위와 같은 Spring Controller가 있다고 하자.
아마 평범하게(?) 이렇게 쓸 것 같다. paging 이 없거나 하면 더 간단하겠지.
그런데 이 코드에 보면 저 request 에서 JPA 의 specification 을 사용하기 위해 getSpecificationFromRequest() 안에 request를 집어 넣는 것을 볼 수 있다.
getSpecificationFromRequest() 는 다음과 같이 생겼다.
받아온 request 안의 값을 사용해서 specification 을 만든다.
이렇게 만든 specification 을 사용해서 DB 에서 Comments 를 꺼내온다.
그런데 이제 여기서 갑자기 변경을 막 가하고 싶어진다.
저렇게 like 검색을 했다간 DB가 많이 힘들어 할 것 같아서 다른 Service 에서 contents를 따로 검색해 와서 검색한 ID를 가져오고 싶다.
그래서 이렇게 변경했다고 해보자. (예시가 적절한지 모르겠다...)
Controller 는 이렇게 바뀌었다.
이제 ids 를 request에 parameter로 넣어줘야 하는데 어떻게 넣어줄 수 있을까?
기본적으로 Spring 에서 HttpServletRequest 는 Immutable 이다.
생각해보면 외부에서 들어온 값을 Immutable 로 받는 것은 당연한데, 어른의 사정이란 건 항상 존재하기 마련이다.
구조적으로 잘못되었거나
(이 경우는 DB에서 SELECT하는 걸 포기하고 통째로 외부에서 검색하는 편이 낫다. 지금은 이렇게 계속 하겠지만, 페이징 등에서 어려움을 또 겪는다.)
이미 레거시가 되어버려서 슬픈 경우...아니면 잘못된 것이 아니라 정말로 특이한 경우일 수도 있다.
이 때는 Immutable 인 request를 억지로 변경하는 것보다 Wrapping을 하는 것이 안전하다.
Spring 에는 HttpServletRequestWrapper 라는 클래스가 있는데, 이것을 확장하면 request를 wrapping 해서 사용할 수 있다.
(참고로 나도 구글링해서 만든 코드라... 출처가 어딘지 기억이 나지 않음;;)
이렇게 HttpServletRequestWrapper 를 확장해서 사용하면 request 값을 변경하지 않고 wrapping 된 request를 다음과 같이 사용할 수 있다.
(일단 보여주기 위해서 변수 정리를 좀 덜했다. search 해서 가져오고 wrapping 된 request 리턴해주는 함수를 하나 더 만들면 깔끔하겠지?)
이렇게 Request 내부의 값을 변경하기 위해 삽질하는 대신, 좀 더 안전하게 수정된 request를 사용할 수 있게 되었다.
wrapping 이라는 아이디어 자체가 꼭 request 처리 뿐만 아니라 다른 곳에서도 유용하게 쓰일 수 있을 것 같아서 굳이 포스팅을 해보았다. (은근 귀찮고 힘드네..ㅠㅜ)
그래도 가장 좋은 건 request 를 wrapping 할 필요 없이 만드는 것 같다.
일단 wrapping할 상황이라는 것 자체가 모델링이 망한 경우일 수도 있고... 여러 모로 반가운 상황은 아닌 듯.
'Tech Note' 카테고리의 다른 글
글로벌 비디오 서비스가 가능하게 한 넷플릭스의 Microservice 아키텍쳐 구조 분석 (1) | 2021.01.24 |
---|---|
Consistent Hashing 일관된 해싱 (0) | 2020.12.27 |
HTTP/2 HTTP/3 의 차이점 (0) | 2019.09.10 |
Group by 에 대해서 (0) | 2019.05.05 |
git 커밋 시간 변경하기 (0) | 2017.05.08 |