넥스트를 app router 방식으로 개발하다보면 메타태그에서 같은 데이터를 중복으로 호출하는 경우가 발생한다.
다음은 Next.js 애플리케이션에서 속성 세부 페이지를 위한 메타데이터 생성을 구현하고,
캐싱을 통해 중복 API 호출을 방지하는 방법에 대한 설명입니다.
메타데이터 생성과 캐싱 처리
- 캐시 설정:
- propertyCache라는 Map 객체를 사용하여 속성 데이터를 캐시합니다. 이 캐시는 속성 ID를 키로 사용하여 데이터를 저장합니다.
const propertyCache = new Map<string, PropertyProps | null>();
속성 데이터 가져오기 함수:
- fetchPropertyCache 함수는 속성 ID를 받아 해당 ID에 대한 속성 데이터를 반환합니다.
- 먼저 캐시를 확인하여 데이터가 있는지 확인합니다. 데이터가 있다면, 해당 데이터를 반환합니다.
- 캐시에 데이터가 없다면, API 호출을 통해 데이터를 가져오고, 캐시에 저장한 후 반환합니다.
export async function fetchPropertyCache(id: string): Promise<PropertyProps | null> { if (propertyCache.has(id)) { return propertyCache.get(id) || null; } console.log("====================캐시 호출 -----"); try { const res = await fetch(`${apiDomain}/api/properties/${id}`); if (!res.ok) { throw new Error("Failed to fetch property"); } const property = await res.json(); propertyCache.set(id, property); return property; } catch (error) { console.error(error); propertyCache.set(id, null); return null; } }
메타데이터 생성:
- generateMetadata 함수는 속성 ID를 받아 해당 속성에 대한 메타데이터를 생성합니다.
- fetchPropertyCache 함수를 사용하여 속성 데이터를 가져옵니다.
- 속성 데이터가 없는 경우, 기본 메타데이터를 반환합니다.
- 속성 데이터가 있는 경우, 속성 이름과 설명을 포함한 메타데이터를 생성하여 반환합니다.
export async function generateMetadata({ params: { id } }: PropertiesDetailPageProps, parent: ResolvingMetadata): Promise<Metadata> { console.log("====================메타 데이터에서 호출 -----"); const property = await fetchPropertyCache(id); if (!property) { return { title: "데이터가 없습니다.", description: "해당 속성에 대한 데이터를 찾을 수 없습니다.", }; } return { title: '부동산 플래닛 | ' + property.name, description: property.description, openGraph: { images: property.images.map((image: string) => ({ url: image, width: 800, height: 600, alt: property.name, })), }, }; }
속성 세부 페이지 컴포넌트:
- PropertiesDetailPage 컴포넌트는 속성 ID를 받아 속성 세부 정보를 표시합니다.
- fetchPropertyCache 함수를 사용하여 속성 데이터를 가져오고, 데이터가 없는 경우 404 페이지를 반환합니다.
- 데이터가 있는 경우, 속성 세부 정보와 이미지를 표시합니다.
const PropertiesDetailPage: NextPage<PropertiesDetailPageProps> = async ({ params }) => { if (!params.id) return notFound(); let property: PropertyProps | null = null; const propertyDoc = await fetchPropertyCache(params.id); if (propertyDoc) { property = convertToSerializableObject(propertyDoc); } if (!property) { return notFound(); } const propertyData: PropertyCardProps = { property: property }; return ( <> <Suspense fallback={<Spinner loading={true} />}> <PropertyHeaderImage image={property.images[0]} name={property.name} /> </Suspense> <section> <div className="container m-auto py-6 px-6"> <Link href="/properties" className="text-blue-500 hover:text-blue-600 flex items-center" > <FaArrowLeft className="mr-2" /> 속성 목록으로 돌아가기 </Link> </div> </section> <section className="bg-blue-50"> <div className="container m-auto py-10 px-6"> <div className="grid grid-cols-1 md:grid-cols-70/30 w-full gap-6"> <Suspense fallback={<Spinner loading={true} />}> <PropertyDetails property={property} /> </Suspense> <PropertyAside property={property} /> </div> </div> </section> <PropertyImages images={property.images} /> </> ); };
요약
- fetchPropertyCache 함수는 속성 데이터를 캐시하여 중복된 API 호출을 방지합니다.
- generateMetadata 함수는 캐시된 데이터를 사용하여 메타데이터를 생성합니다.
- PropertiesDetailPage 컴포넌트는 캐시된 데이터를 사용하여 속성 세부 정보를 표시합니다.
이와 같이 캐시를 활용하면 성능을 향상시키고 불필요한 API 호출을 줄일 수 있습니다.
댓글 ( 0)
댓글 남기기