notion 페이지 임베딩! 처음 회사를 입사하고 담당했던 업무였다!
운영에 관련한(개인정보처리방침, FAQ, 당첨자 발표 등) 내용을 하드 코딩으로 관리하기보다는 운영팀에서 노션으로 직접 운영하고, 빠른 적용이 가능하도록 노션 임베드 페이지를 도입하게 된 것이다.
그렇게 코린이 시절 어찌어찌 구현한 코드로 몇 개월이 지난 후, "이벤트" 서비스가 생겨나면서 당첨자 발표 페이지를 임베딩 해두고 test를 하던 중...
노션 내용을 변경하면, 유저가 2번째 페이지를 방문하는 시점에만 새로운 변경사항이 적용되는 문제가 있었다.
다른 페이지들은 큰 변경 사항이 없는 내용이지만, 당첨자 발표와 같은 페이지는 한 번 유저가 진입하면, "아 나 떨어졌나보다..." 하고, 다시 들어가서 확인할 가능성이 적을 것이라는 문제를 인식하고 해당 캐싱 문제는 꼭 해결이 필요했다.
처음엔 react-notion
라이브러리 자체에 캐싱이 되어있나? 라고 생각했지만, 시간에 따른 캐싱도 아니고 횟수에 따른 캐싱이었기 때문에 block data를 받아오는 api 코드에서 캐싱이 된다고 판단하게 되었다.
여기서 잠깐!
react-notion
은 api로 받아 온 노션 컨텐츠를 (block data) 임베딩하여 그리도록 도와주는 라이브러리이며,
notion-api-worker
는 노션 컨텐츠를 get해오는 오픈 api입니다.
react-notion
라이브러리에서 제공하는 샘플 코드를 보면, https://notion-api.splitbee.io/v1/page/
를 통해 notion page의 block data를 받아오도록 작성되어있다.
해당 api는 react-notion
에서 함께 만든 notion-api-worker
라는 오픈 소스를 통해 제공되고 있었고, 해당 라이브러리에서 캐시를 하고 있었던 것이다.
해당 깃허브 이슈탭을 보면 request header에 no-cache가 있다면, 새로운 데이터를 반환하도록 하는 내용들이 종종 있어 적용을 한 듯 보였다.
해당 내용 : get-cache-key
export function getCacheKey(request: Request): string | null {
const pragma = request.headers.get("pragma");
if (pragma === "no-cache") {
return null;
}
const cacheControl = request.headers.get("cache-control");
if (cacheControl) {
const directives = new Set(cacheControl.split(",").map((s) => s.trim()));
if (directives.has("no-store") || directives.has("no-cache")) {
return null;
}
}
return request.url;
}
해당 오픈소스에서 CacheKey를 가져오는 코드 입니다.
request header에 "no-cache"를 보내면, CacheKey를 사용하지 않네요!
import axios from 'axios';
import { BlockMapType } from 'react-notion';
export async function getNotionPage(notionPageId: string): Promise<BlockMapType> {
const url = `/v1/page/${notionPageId}`;
const { data } = await notionApiAxios.get<BlockMapType>(url);
return data;
}
const notionApiAxios = axios.create({
baseURL: 'https://notion-api.splitbee.io',
});
notionApiAxios.interceptors.request.use((config) => {
config.headers.Pragma = 'no-cache'; // no-cache
return config;
});
그래서 request header에 no-cache를 보내도록 코드를 수정하니, 노션 수정사항을 바로 확인할 수 있었다!!