OI7MI
[React] TMDB API: 한 번의 요청으로 영화 상세정보와 유튜브 예고편 가져오기 본문

1. 문제 상황: "데이터가 부족하다?"
기존에 사용하던 영화 상세 정보 API 호출 방식으로는 영화의 줄거리나 평점 정보는 가져올 수 있었지만
영화의 핵심 콘텐츠라고 할 수 있는 ‘예고편 영상’ 데이터가 포함되어 있지 않았다.
이를 어떻게 해결할 수 있을지 고민하던 중,
TMDB에서 제공하는 append_to_response 기능을 사용하기로 했다.
기존에 사용하던 API 호출 방식은 다음과 같다.
const url = `https://api.themoviedb.org/3/movie/${id}?language=ko-KR`;
여기에 유튜브 예고편 영상을 함께 가져오기 위해
아래와 같이 append_to_response=videos 옵션 추가
const url = `https://api.themoviedb.org/3/movie/${id}?language=ko-KR&append_to_response=videos`;
2. 예외 처리: "데이터가 항상 Trailer인 것은 아니다"
데이터를 분석해보니
한국어(ko-KR) 설정 시 예고편이 항상 Trailer 타입으로만 제공되지 않는다는 것을 알게 되었다.
경우에 따라 Featurette(제작기)나 Teaser로 들어오는 경우도 있었고,
이대로라면 예고편이 있음에도 불구하고 사용자에게 아무것도 보여주지 못하는 상황이 발생할 수 있었다.
그래서 사용자에게 ‘뭐라도’ 보여주기 위해 아래와 같은 영상 타입 우선순위 로직을 구현했다.
// 영상 타입 우선순위 로직
const video =
results.find((v) => v.type === "Trailer") || // 1순위: 공식 예고편
results.find((v) => v.type === "Teaser") || // 2순위: 티저
results.find((v) => v.type === "Featurette") || // 3순위: 특별 영상
results[0]; // 4순위: 그 외 첫 번째 영상
3. 보안 및 사용자 경험
유튜브 링크를 열 때는 window.open을 사용해 새 탭에서 열리도록 설정했다.
이를 통해 사용자가 서비스 페이지를 이탈하지 않으면서도 영상을 감상할 수 있도록 UX를 고려했다.
아래는 전체 코드다.
const showYouTube = () => {
if (!movie || !movie.videos || movie.videos.results.length === 0) {
alert("제공되는 YouTube 예고편이 없습니다.");
return;
}
const results = movie.videos.results;
const video =
results.find((v) => v.type === "Trailer") || // 1순위: 공식 예고편
results.find((v) => v.type === "Teaser") || // 2순위: 티저
results.find((v) => v.type === "Featurette") || // 3순위: 특별 영상
results[0]; // 4순위: 그 외 첫 번째 영상
if (video && video.site === "YouTube") {
window.open(`https://www.youtube.com/watch?v=${video.key}`, "_blank");
} else {
alert("YouTube 영상을 찾을 수 없습니다.");
}
}
<button onClick={showYouTube}>예고편 보기</button>

동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
마무리
API 데이터를 다룰 때 단순히 매뉴얼만 따라가는 것이 아니라,
실제 응답 데이터(results)의 구조를 console.log로 직접 확인하며
상황에 맞는 예외 처리를 해주는 과정이 얼마나 중요한지 배울 수 있었다.
'프론트엔드 > React' 카테고리의 다른 글
| [React] 별점(Star Rating) 라이브러리로 구현하기 (0) | 2026.01.15 |
|---|---|
| [React] 리액트 <Link>와 HTML <a>의 차이점 (feat. CSS가 안 먹히는 이유) (0) | 2026.01.15 |
| [React] API 호출 .then() 대신 async-await 처리 (0) | 2026.01.13 |
| [React] useState 상태 업데이트와 배열에서 특정 항목 삭제하기 (0) | 2026.01.09 |
| [React] useEffect() 와 Cleanup 함수 (0) | 2026.01.07 |