주니어 개발자 1호

apollo client refetchQueries 분석.. 본문

Front 관련

apollo client refetchQueries 분석..

No_1 2024. 8. 27. 10:44

사내 FE분과 협업중에 특정 API를 호출할 때, 이미 받아온 데이터 ( Cached )를 refetch해야했는데, 해당 refetchQuries가 동작하지 않는 이슈를 공유 받았다. 

 

refethQuries 쿼리 요청 방법 -> DocumentNode, String, Object의 형태로 보낼 수 있다.

ref: https://www.apollographql.com/docs/react/data/mutations/#refetching-queries

 

Mutations in Apollo Client

Modify data with the useMutation hook

www.apollographql.com

공식문서에서는 세 방법 다 유효하다고 안내되어 있는데, 실제로 매끄럽게 되지 않았는데..

String, DocumentNode => refetch 동작하지 않음

Object{ query: #name } => refetch 동작

 

이유가 궁금해서 node_modules를 debug로 1차로 분석, 실제 구현되어 있는 github code를 2차적으로 확인했다.

 

원인은 apollo client의 src/core에 QueryManger를 보면 확인할 수 있는데, 

https://github.com/apollographql/apollo-client/blob/5002b9454ac8769b214d3f5a517b6164f221bdfc/src/core/QueryManager.ts#L860

 

apollo-client/src/core/QueryManager.ts at 5002b9454ac8769b214d3f5a517b6164f221bdfc · apollographql/apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server. - apollographql/apollo-client

github.com

 

queries에 들어온 요청을 아래와 같이 "queryNamesAndDocs, legacyQureyOptions"의 두 형태로 나누어서 배열로 저장한다.

 

 if (Array.isArray(include)) {
      include.forEach((desc) => {
        if (typeof desc === "string") {
          queryNamesAndDocs.set(desc, false);
        } else if (isDocumentNode(desc)) {
          queryNamesAndDocs.set(this.transform(desc), false);
        } else if (isNonNullObject(desc) && desc.query) {
          legacyQueryOptions.add(desc);
        }
      });
    }

 

새롭게 API를 요청하는 배열은 legacyQureyOptions으로써, 위의 git code 내에서 해당 부분을 찾으면 보인다.

if (legacyQueryOptions.size) {
      legacyQueryOptions.forEach((options: QueryOptions) => {
        // We will be issuing a fresh network request for this query, so we
        // pre-allocate a new query ID here, using a special prefix to enable
        // cleaning up these temporary queries later, after fetching.
        const queryId = makeUniqueId("legacyOneTimeQuery");
        const queryInfo = this.getQuery(queryId).init({
          document: options.query,
          variables: options.variables,
        });
        const oq = new ObservableQuery({
          queryManager: this,
          queryInfo,
          options: {
            ...options,
            fetchPolicy: "network-only",
          },
        });
        invariant(oq.queryId === queryId);
        queryInfo.setObservableQuery(oq);
        queries.set(queryId, oq);
      });
    }

 

 

 

----

useMutation의 method내에서 mutate를 호출하는데, 이에 대한 코드를 따라가면 만날 수 있었다.

'Front 관련' 카테고리의 다른 글

Vue emit 관련  (0) 2022.07.20
Vue axios 세팅  (0) 2022.07.20
Vue html2canvas 사용 방법  (0) 2022.07.19