티스토리 뷰

Spring/Spring Data

[Redis] HATEOAS와 @Cacheable

ryumodern 2021. 9. 20. 15:05

이전 Redis 삽질기에서 해결법은 찾지 못 했으나 타협점을 찾았기 때문에 올린다

내가 의도 했던 것은 RestController 응답을 HATEOAS에 맞춰 

ResponseEntity<EntityModel> 또는 ResponseEntity<CollectionModel>로 내려주려고 했다

또한 응답 결과의 더 빠른 제공을 위해 spring-data-redis의 @Cacheable을 사용하려고 했다

그런데 EntityModel은 Serializable을 구현하지 않고, 독자적인 deserializer를 사용하고 있기 때문에

EntityModel에 @Cacheable을 사용한 방식으로 응답을 내려주면 아래와 같은 에러를 만날 수 있다

 

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Type id handling not implemented for type java.lang.Object (by serializer of type org.springframework.hateoas.EntityModel$MapSuppressingUnwrappingSerializer)

 

 

응급 처치로 EntityModel을 한번 감싸주기만 하는 Custom Wrapper 객체를 만들어 

ResponseEntity<Result<EntityModel>>로 반환을 하니 @Cacheable도 잘 동작하여 응답을 내려줬다

 

Custom Wrapper 객체

 

 

이 방식의 치명적인 단점은 응답 결과에 있다 아래 사진 좌측과 같은 방식으로 응답이 나간다

Custom Wrapper인 Result로 한번 감싸기 때문에 EntityModel의 응답 형식이 깨져 

_links : {...} 가 아닌 links : [...] 로 나타난다 

특히 rel : href 관계가 깨지는 것이 더 심각하다 사용은 할 수 있겠지만 응답 형태가 맘에 들지가 않았다 

(좌) 원하지 않은 응답 형태 (우) 원하는 응답 형태

 

 

그래서 타협점은 일단 @Cacheable을 걷어내기로 했다

Redis를 공부하고 처음 써보는 상황이었기 때문에 성급하게 적용한 것 같다

개발자 친구의 프로젝트 피드백 덕에 단순 회원 정보 조회에 Cache를 써야할 필요가 있나 생각이 들기도 한다

@Cacheable은 거의 변하지 않는 대량의 정보만 내려줄 때 사용하기로 하고

HATEOAS를 지키는 쪽에서는 그냥 캐시 없이 쿼리를 날리기로 결정했다

성능 상의 이유로 Cache를 적용하는게 아니라 Cache를 걷어내도 상관은 없는데 괜히 아쉬운 기분이다

다음에 적절한 곳에 꼭 써봐야지

 

 

혹시나 무조건 HATEOAS와 @Cacheable을 같이 쓰고 싶은 상황이라면

응답 형태는 못난이지만 ResponseEntity<Wrapper<EntityModel>>의 형태로 사용하면 된다

응답 형식에서 LocalDateTime이 깨지던 상황도 해결했다

@JsonFormat 없이도 아래 새롭게 바꾼 ObjectMapper 코드를 적용하니 전역으로 간단하게 된다

 

 

- 이 전에 사용하던 objectMapper 생성 코드

@Bean
public ObjectMapper objectMapper() {
  return Jackson2ObjectMapperBuilder.json().build()
      .enableDefaultTyping(DefaultTyping.NON_FINAL)
      .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
      .setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
      .registerModules(new JavaTimeModule());
}

 

- 새롭게 바꾼 objectMapper 생성 코드

@Bean
public ObjectMapper objectMapper() {
  return new ObjectMapper()
	  .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
	  .registerModule(new JavaTimeModule());
}

 

 

 

 


이어지는 글

 

[Redis] HATEOAS와 @Cacheable - 2

[Redis] HATEOAS와 @Cacheable 이전 Redis 삽질기에서 해결법은 찾지 못 했으나 타협점을 찾았기 때문에 올린다 내가 의도 했던 것은 RestController 응답을 HATEOAS에 맞춰 ResponseEntity 또는 ResponseEntity..

ryumodrn.tistory.com

 

댓글
링크
글 보관함
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday