Graphql Apollo client의 fetchPolicy 옵션

ashnamuh·2019년 10월 31일
5
post-thumbnail

최근 회사에서 백엔드 api는 Graphql로, 프론트엔드는 Vue로 작업하고 있다.

나는 프론트엔드에서 vue-apollo라는걸 사용해서 Graphql을 연동해서 사용한다.

이걸 사용하면서 새롭게 알게된 ApollofetchPolicy에 대해 간략히 설명하고자 한다.

fetchPolicy 옵션이란?

Apollo client에서 graphql을 사용해서 서버에서 데이터를 받아온다. 이 데이터를 메모리 캐시에 저장해뒀다가 같은 쿼리를 요청하면 캐시에 저장된걸 받아오거나 캐시를 무시하거나 할 수 있다. 이를 정해주는 옵션이 fetchPolicy 이다. 이를 적절히 사용하면 HTTP 요청을 최적화하고 캐시 데이터 공유를 쉽게 할 수 있다.

cache-first

이 옵션이 기본값이고 다음 단계로 동작하는데, 2단계에서 멈출 수도 있다.

  1. 쿼리를 사용할 때 캐시를 확인한다.
  2. 캐시 데이터가 있으면 이를 반환한다. 없으면 3단계로 넘어간다.
  3. 서버에 쿼리를 사용해서 데이터를 요청한다.
  4. 캐시 데이터를 업데이트한다.
  5. 받아온 데이터를 반환한다.

캐시 데이터를 먼저 확인하니, 불필요한 HTTP 요청을 줄여준다. 서버에서 최초 받아오고, 그 이후엔 변경될 여지가 적은 데이터에 유용하다. 예를 들면 시, 도, 군, 구 등의 주소 데이터는 쉽게 변경되지 않으니 이에 사용하면 좋을 거 같다.

cache-and-network

이 옵션은 다음 5단계가 무조건 실행된다.

  1. 쿼리를 사용할 때 캐시를 확인한다.
  2. 캐시 데이터가 있으면 일단 이를 반환한다.
  3. 2단계의 캐시 데이터 유무와 무관하게 서버에 쿼리를 사용해서 데이터를 요청한다.
  4. 캐시 데이터를 업데이트한다.
  5. 받아온 데이터를 반환한다.

이 옵션의 핵심은 캐시 데이터와 무관하게 HTTP 요청이 발생한다는 것이다. 단, 요청이 발생하기 전 캐시 데이터가 있으면 일단 반환한다. 실시간으로 변경이 잦은 데이터의 빠른 응답 속도를 위해 캐시 데이터를 먼저 반환하고 이후에 서버에서 받아온 데이터를 응답할 때 유용할 것 같다.

network-only

이 옵션은 다음 3단계로 동작한다.

  1. 서버에 쿼리를 사용해서 데이터를 요청한다.
  2. 캐시 데이터를 업데이트한다.
  3. 받아온 데이터를 반환한다.

cache-and-network 옵션의 경우 만료된(outdated) 캐시 데이터를 초기에 보여줄 수 있다는 단점이 있다. 이 옵션을 사용하면 캐시 데이터를 확인하지 않고 무조건 HTTP 요청을 실행한다.

cache-only

이 옵션은 HTTP 요청이 발생하지 않는 2단계로 동작한다.

  1. 쿼리를 사용할 때 캐시를 확인한다.
  2. 캐시 데이터가 있으면 이를 반환하고 없으면 에러를 발생시킨다.

무조건 캐시 데이터만 반환한다. 캐시 데이터가 없으면 에러를 발생시키므로 주의해서 사용해야한다.

no-cache

이 옵션도 간단하게 2단계로 동작한다.

  1. 서버에 쿼리를 사용해서 데이터를 요청한다.
  2. 받아온 데이터를 반환한다.

network-only 옵션에서 캐시 데이터를 업데이트하는 동작을 하지 않는 것이다.

여담 - Nuxt + Vue에서 Apollo 조금 사용해본 후기

현재 nuxt-apollo라는 vue-apolloNuxt에서 쓸 수 있게 만든 오픈소스를 사용한다. 아직 서비스 개발 초기 단계인데, 아쉬움이 느껴진다.

첫번째로는 서버 사이드 렌더링 지원이 미흡하다는 것이다. vue-apollo에서 제공하는 스마트쿼리라는 것을 통해 Vue 컴포넌트 내에서 쿼리를 사용하는데, Nuxt의 The client-side rendered virtual DOM tree is not matching server-rendered content. 에러가 발생한다. 공식 문서대로 따라했지만, 내가 설정을 잘못한 것일 수 있다.

두번째로는 fetchPolicy 옵션이 예상대로 동작하지 않는다. 일단 서버 사이드 렌더링 시 스마트쿼리가 실행되면 설정한 옵션과는 무관하게 캐시 데이터가 무조건 저장되는 동작을 확인했다. 버그인지, 원래 동작인데 문서화가 안된 것인지 모르겠다. 공식 문서에서도 이와 관련된 내용은 찾지 못했다. 이참에 이슈 남기고 문서화 기여를 해볼까?

전술한 두가지가 아쉽지만 Graphql은 확실히 좋다. 오히려 개발 속도가 빨라졌고, 상태 관리도 쉽게 된다. 가장 마음에 드는 점은 REST Api 처럼 Vue, React 등 환경에 독립적인 기술이라는 것이다. 지금은 Vue로 개발하고 있지만 나중에 Angular, React를 할 기회가 오더라도 Graphql을 활용할 수 있다.

profile
프론트엔드 개발자입니다

0개의 댓글