Apollo Client의 캐시
- GraphQL 데이터를 효율적으로 저장하고 관리하기 위한 메커니즘이다.
- 이를 통해 네트워크 요청을 최소화하고, 사용자 경험을 개선할 수 있다.
- Apollo Client의 기본 캐시는 InMemoryCache로, 이는 데이터를 메모리에 저장하고, 이를 통해 빠르게 데이터에 접근할 수 있다.
주요 특징과 사용 방법
기본적인 캐싱 동작
- Apollo Client는 쿼리 요청 시 서버로부터 데이터를 받아 캐시에 저장한다.
- 이후 동일한 쿼리가 발생하면 캐시에서 데이터를 불러오기 때문에 네트워크 요청을 다시 보내지 않아도 된다.
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
const client = new ApolloClient({
uri: '<https://example.com/graphql>',
cache: new InMemoryCache(),
});
client.query({
query: gql`
query GetUsers {
users {
id
name
}
}
`,
});
여기서 InMemoryCache가 쿼리 결과를 캐시에 저장하고, 이후 동일한 쿼리 요청이 있으면 캐시에서 바로 데이터를 반환한다.
캐시 정책
Apollo Client는 여러 캐시 정책을 통해 네트워크 요청과 캐시 동작을 제어할 수 있다:
- cache-first: 기본 설정. 캐시에 데이터가 있으면 네트워크 요청을 보내지 않는다.
- network-only: 항상 네트워크 요청을 보내고, 응답을 받은 후 캐시에 저장한다.
- cache-only: 오직 캐시에서만 데이터를 가져온다.
- no-cache: 캐시를 사용하지 않고 네트워크 요청만을 사용한다.
client.query({
query: gql`
query GetUsers {
users {
id
name
}
}
`,
fetchPolicy: 'network-only', // 네트워크에서만 데이터 가져오기
});
캐시 관리
자동 업데이트
- Apollo Client는 GraphQL 객체의 id 필드와 __typename을 기반으로 캐시를 자동으로 업데이트한다.
- 이를 통해 쿼리나 변이 요청 후 캐시에 있는 관련 데이터를 자동으로 갱신할 수 있다.
const cache = new InMemoryCache({
typePolicies: {
User: {
keyFields: ['id'], // 캐시에서 id를 기반으로 유저를 식별
},
},
});
수동 업데이트
- 때로는 쿼리나 변이 결과에 따라 캐시를 수동으로 업데이트해야 할 때도 있다.
- 이를 위해 cache.writeQuery, cache.writeFragment, cache.modify와 같은 메서드를 사용한다.
// 특정 변이 후 캐시 업데이트
client.mutate({
mutation: gql`
mutation AddUser($name: String!) {
addUser(name: $name) {
id
name
}
}
`,
update(cache, { data: { addUser } }) {
cache.modify({
fields: {
users(existingUsers = []) {
const newUserRef = cache.writeFragment({
data: addUser,
fragment: gql`
fragment NewUser on User {
id
name
}
`,
});
return [...existingUsers, newUserRef];
},
},
});
},
});
캐시 초기화 및 재설정
- cache.reset()은 캐시를 초기화할 때 사용된다.
- 이는 일반적으로 사용자가 로그아웃하거나 세션이 만료되었을 때 캐시를 비울 필요가 있을 때 사용된다.
client.cache.reset(); // 캐시 초기화
InMemoryCache 구성 요소
Normalization:
- GraphQL의 구조화된 데이터는 id와 __typename을 이용해 캐시에 효율적으로 저장된다.
- 이를 통해 중복 데이터가 최소화된다.
Field Policies
- 특정 필드에 대한 캐시 동작을 커스터마이징할 수 있다.
- 예를 들어, 페이지네이션 데이터는 특정 방식으로 병합해야 할 수 있다.
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
users: {
keyArgs: false, // keyArgs: false로 설정하면 페이지네이션 처리 가능
merge(existing = [], incoming) {
return [...existing, ...incoming];
},
},
},
},
},
});
이러한 캐시 기능을 통해 Apollo Client는 네트워크 요청을 줄이고, 빠르게 데이터를 제공할 수 있다.
'Frontend > Apollo' 카테고리의 다른 글
useLazyQuery, GraphQL 쿼리를 즉시 실행하지 않고 필요할 때 호출 (0) | 2024.10.15 |
---|---|
GraphQL 서버와 통신하지 않고 Apollo Client 캐시에서 직접 데이터를 읽고 쓰기 (0) | 2024.10.01 |
Apollo Link 개요와 주요 기능 (0) | 2024.09.29 |
GraphQL Code Generator, 타입스크립트 정의 자동 생성 (0) | 2024.09.10 |
[Apollo v.3] Reactive variables (0) | 2024.09.06 |