반응형

📝캐싱

enum CacheControlScope {
  PUBLIC
  PRIVATE
}

directive @cacheControl(
  maxAge: Int
  scope: CacheControlScope
  inheritMaxAge: Boolean
) on FIELD_DEFINITION | OBJECT | INTERFACE | UNION


/** 예제 (필드 캐싱) **/
type Post {
  id: ID!
  title: String
  author: Author
  votes: Int @cacheControl(maxAge: 30)
  comments: [Comment]
  readByCurrentUser: Boolean! @cacheControl(maxAge: 10, scope: PRIVATE)
}

/** 예제 (타입 캐싱) **/
type Post @cacheControl(maxAge: 240) {
  id: Int!
  title: String
  author: Author
  votes: Int
  comments: [Comment]
  readByCurrentUser: Boolean!
}

/** 우선 캐싱순위 필드 우선 [상세한 거 우선] **/
type Comment {
  post: Post! # Cached for up to 240 seconds
  body: String!
}

type Comment {
  post: Post! @cacheControl(maxAge: 120)
  body: String!
}

지시어를 추가해야 사용할 수 있다

 

maxAge cache 유지 기간로 Default값은 0이다
scope cache 유지 범위 PUBLIC이 Default값이며 Private의 경우 단일 사용자에 대한 캐시 유지 범위이다
inheritMaxAge 상위 필드에 maxAge가 있는 경우 그걸 상속받아서 사용한다

 

 

📝 리졸버에서 캐싱 사용하기

/** cacheControl.setCacheHint로 캐싱 설정하기 **/
import { cacheControlFromInfo } from '@apollo/cache-control-types';

const resolvers = {
  Query: {
    post: (_, { id }, _, info) => {
      // Access ApolloServerPluginCacheControl's extension of the GraphQLResolveInfo object
      const cacheControl = cacheControlFromInfo(info)
      cacheControl.setCacheHint({ maxAge: 60, scope: 'PRIVATE' });
      return find(posts, { id });
    },
  },
};

/** cacheControl.cacheHint 필드의 현재 캐시 힌트 확인 **/
import { cacheControlFromInfo } from '@apollo/cache-control-types';

const resolvers = {
  Query: {
    post: (_, { id }, _, info) => {
      // Access ApolloServerPluginCacheControl's extension of the GraphQLResolveInfo object
      const cacheControl = cacheControlFromInfo(info)
      cacheControl.setCacheHint({ maxAge: 60, scope: 'PRIVATE' });
      return find(posts, { id });
    },
  },
};

 

 

📝 플러그인 캐싱 (커스텀 캐싱)

new ApolloServer({
  plugins: [
    ApolloServerPluginCacheControl({ calculateHttpHeaders: false }), // 아폴로 서버 캐싱 헤더 설정 중지
    {
      async requestDidStart() {
        return {
          async willSendResponse(requestContext) {
            // 캐싱 커스텀 설정
            const { response, overallCachePolicy } = requestContext;
            const policyIfCacheable = overallCachePolicy.policyIfCacheable();
            if (policyIfCacheable && !response.headers && response.http) {
              response.http.headers.set(
                'cache-control',
                // ... or the values your CDN recommends
                `max-age=0, s-maxage=${
                  overallCachePolicy.maxAge
                }, ${policyIfCacheable.scope.toLowerCase()}`,
              );
            }
          },
        };
      },
    },
  ],
});

직접 플러그인에다가 캐싱을 커스텀하는 방법도 존재하며 메모리 미들웨어인 Redis등과 같이 사용할 수도 있습니다

 

자세한 건 캐시 인메모리 구현에 대해서 참고 바랍니다

https://www.apollographql.com/docs/apollo-server/performance/caching

https://www.apollographql.com/docs/apollo-server/performance/cache-backends/

 

 

일반적으로 스키마의 모든 필드 에 캐시 힌트를 지정할 필요는 없다네요 성능에 대해서 개선시킬 가능성이 있을 경우에 이용하면 좋을 거 같습니다

 

 

반응형