LANGUAGE/React

[Next.js] TMDB Movie Collection 가져오기/ 영화 컬렉션, 시리즈 가져오는 법

31daylee 2024. 6. 27. 11:12
728x90

📌 TMDB API Document 공식 사이트


https://developer.themoviedb.org/reference/intro/getting-started

 

Getting Started

Welcome to version 3 of The Movie Database (TMDB) API. This is where you will find the definitive list of currently available methods for our movie, tv, actor and image API.

developer.themoviedb.org

 

 

 

 

📌 Movie 컬렉션/시리즈 가져오는 법


🤯상황 

TMDB API 를 이용해서 Moive Application을 만드는 와중, 한 영화에 해당하는 Collection/Series 리스트를 가져오고 싶었다. 영화 마블로 치면, <어벤져스> 편 디테일에 들어가면 이와 관련된 다른 마블 시리즈 <아이언맨>, <엔드게임> 등을 리스트로 보여주고 싶었다. 하루 꼬박 세워 온갖 커뮤니티, 블로그 , 깃헙 소스 등을 찾아봤지만 이와 같은 레퍼런스는 찾지 못했고... Search를 통해 해야하나? 라는 상황에 놓여져 있었다. (Search는 param통해서 title을 검색할까 했는데, title 가 똑같으면 시리즈 상관없이 다 불러오기에 이 방식은 패스했다.) 

 

Collection을 가져오는 방법이 없을까? 하다가 TMDB 공식 사이트에선 제공하는 것을 확인했다.

https://www.themoviedb.org/collection/1022790-inside-out-collection

 

 

삽질의 삽질의 반복을 끝내고 드디어 찾아내서 나와 같은 방식으로 헤매는 사람들에게 도움을 주고자 포스팅을 하게 되었다. 

 

 

 

 

😁컬렉션 목록 가져오기

1. 영화의 디테일에서 collection id를 가져온다.

https://developer.themoviedb.org/reference/movie-details

 

Details

Get the top level details of a movie by ID.

developer.themoviedb.org

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

 

Details

Get collection details by ID.

developer.themoviedb.org

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를 뽑아낼 수 있다 !! 

 

 

 

 

 

 

728x90