[Next.js] TMDB Movie Collection 가져오기/ 영화 컬렉션, 시리즈 가져오는 법
📌 TMDB API Document 공식 사이트
https://developer.themoviedb.org/reference/intro/getting-started
📌 Movie 컬렉션/시리즈 가져오는 법
🤯상황
TMDB API 를 이용해서 Moive Application을 만드는 와중, 한 영화에 해당하는 Collection/Series 리스트를 가져오고 싶었다. 영화 마블로 치면, <어벤져스> 편 디테일에 들어가면 이와 관련된 다른 마블 시리즈 <아이언맨>, <엔드게임> 등을 리스트로 보여주고 싶었다. 하루 꼬박 세워 온갖 커뮤니티, 블로그 , 깃헙 소스 등을 찾아봤지만 이와 같은 레퍼런스는 찾지 못했고... Search를 통해 해야하나? 라는 상황에 놓여져 있었다. (Search는 param통해서 title을 검색할까 했는데, title 가 똑같으면 시리즈 상관없이 다 불러오기에 이 방식은 패스했다.)
Collection을 가져오는 방법이 없을까? 하다가 TMDB 공식 사이트에선 제공하는 것을 확인했다.
삽질의 삽질의 반복을 끝내고 드디어 찾아내서 나와 같은 방식으로 헤매는 사람들에게 도움을 주고자 포스팅을 하게 되었다.
😁컬렉션 목록 가져오기
1. 영화의 디테일에서 collection id를 가져온다.
https://developer.themoviedb.org/reference/movie-details
API Reference -> MOVIES -> Details -> movie_id 입력 -> belongs_to_collection의 id 가져오기
GET
https://api.themoviedb.org/3/movie/{movie_id}
2. Collection Id를 가지고 Collection 디테일에서 해당하는 parts를 가져온다.
https://developer.themoviedb.org/reference/collection-details
API Reference -> COLLECTIONS -> Details -> collection_id 입력 -> parts (관련된 컬렉션 목록)
GET
https://api.themoviedb.org/3/collection/{collection_id}
👩💻관련 코드
// movie-collection.tsx
"use client";
import { IMAGE_URL } from "../app/constants";
import { useEffect, useState } from "react";
import {
getCollectionId,
getCollection,
} from "../app/(movies)/movies/[id]/action";
interface Collection {
id: number;
name: string;
poster_path: string;
backdrop_path: string;
}
interface Parts {
id: number;
title: string;
poster_path: string;
overview: string;
release_date: string;
vote_average: number;
}
export default function MovieCollection({ id }: { id: string }) {
const [collection, setCollection] = useState<Collection | undefined>();
const [parts, setParts] = useState<Parts[] | undefined>();
useEffect(() => {
(async function fetchCollection(id: string) {
const collectionData = await getCollectionId(id);
setCollection(collectionData);
if (collectionData) {
const partsData = await getCollection(collectionData.id);
setParts(partsData);
}
})(id);
}, [id]);
return (
<div>
{collection && (
<>
<h1}>Collection: {collection.name}</h1>
<div>
<img
src={`${IMAGE_URL.SMALL}${collection.poster_path}`}
className={styles.poster}
alt={collection.name}
/>
<div>
<p>{collection.name}</p>
</div>
</div>
</>
)}
{parts &&
parts.map((part) => (
<div key={part.id}>
<img
src={`${IMAGE_URL.SMALL}${part.poster_path}`}
className={styles.poster}
alt={part.title}
/>
<div>
<p>{part.title}</p>
<p>{part.overview}</p>
<p>
Release Date: {part.release_date}
</p>
<p>Rating: {part.vote_average}</p>
</div>
</div>
))}
</div>
);
}
// action.ts
"use server";
import { API_URL } from "../../../constants";
import { COLLECTION_URL } from "../../../constants";
const apiKey = process.env.API_KEY;
export async function getCollectionId(id: string) {
const response = await fetch(`${API_URL}${id}?api_key=${apiKey}`);
if (!response.ok) {
throw new Error(`Failed to fetch collection for movie with id ${id}`);
}
const data = await response.json();
return data.belongs_to_collection;
}
export async function getCollection(id: string) {
const response = await fetch(`${COLLECTION_URL}${id}?api_key=${apiKey}`);
if (!response.ok) {
throw new Error(`Failed to fetch collection list for movie with id ${id}`);
}
const data = await response.json();
return data.parts;
}
상단 컬렉션에서 다음과 같이 Parts를 뽑아낼 수 있다 !!