팀 프로젝트에서 Spotify API를 활용하기로 결정했지만, 이후 API가 제공하는 기능과 데이터가 기획 방향과 맞지 않는다는 문제점을 발견했다. 프로젝트 기간이 일주일도 채 되지 않는 짧은 시간이었기에, 기획을 전면 수정하는 것은 현실적으로 어려웠다. 이에 기존 기획을 유지하면서도 문제를 해결할 수 있는 대안을 모색하여 프로젝트를 진행하기로 결정했다.
플레이리스트의 트랙 중 미리듣기 음원 데이터(preview_url)가 없는 경우는 null로 명시적으로 값을 지정해, 클라이언트에서 조건에 따라 사용할 수 있도록 해줬다.
미리 듣기 음원 처리
const isPlayingAvailable = track.preview_url;
서버 측 데이터
const processedPlaylist: SpotifyPlaylistTracks = { id: playlistResponse.data.id, name: playlistResponse.data.name, external_urls: { spotify: playlistResponse.data.external_urls.spotify }, tracks: tracksResponse.data.items.map((item) => ({ ...item.track, preview_url: item.track.preview_url ?? null, external_urls: { spotify: item.track.external_urls.spotify } })) };
트랙이 담겨있는 플레이리스트 ID에 대한 정보만 얻을 수 있는 api가 없었기 때문에 따로 플레이리스트를 찾아 필요한 메타 데이터만 정리해 데이터베이스에서 따로 관리하기로 결정했다.
Supabase DB에서 가져온 플레이리스트 ID를 활용해 트랙 정보를 가져와 플레이리스트별 트랙을 보여준다.
const playlistsWithTracks = await Promise.all( ... )
이 때 Promise.all
을 사용해 필요한 API 요청을 병렬 처리하여 로딩 시간을 최소화했으며, 에러가 발생한 요청은 null
값을 반환하도록 설정하고, 이를 UI에서 필터링하여 사용자에게 오류 없이 올바른 플레이리스트만 표시되도록 구현했다.
- 속도 측정 테스트
- 순차 실행 속도 : 6550ms
- 병렬 실행 속도 : 1350ms- 결론
병렬 실행 > 순차 실행 : 75.43% 더 빠름
export const GET = async () => {
const playlistsIds = await getPlaylistIdList();
try {
const playlistsWithTracks = await Promise.all(
playlistsIds.map(async (playlistId) => {
try {
const [playlistResponse, tracksResponse] = await Promise.all([
spotifyApiAxios.get<SpotifyPlaylist>(`/playlists/${playlistId}`, {
headers: {
"Content-Type": "application/json"
}
}),
spotifyApiAxios.get<{ items: { track: SpotifyTrack }[] }>(`/playlists/${playlistId}/tracks`, {
params: {
fields:
"items(track(id,name,preview_url,external_urls,duration_ms,artists(id,name),album(id,name,images)))",
limit: 8
}
})
]);
// ... 플레이리스트 트랙 관련 로직
return processedPlaylist;
} catch (error) {
console.error(`Error fetching playlist ${playlistId}:`, error);
return null;
}
})
);
const validPlaylists = playlistsWithTracks.filter((playlist) => playlist !== null);
return NextResponse.json(validPlaylists);
} catch (error) {
console.error("Error fetching track:", error);
return NextResponse.json({ error: "Failed to fetch playlists data" }, { status: 500 });
}
};
Spotify api에서 제공되는 인기 플레이리스트 데이터가 있었다. 기획 상 모든 플레이리스트를 보여줄 필요는 없었고, 대신 추천하는 한 가지만 보여주되 매번 다른 플레이리스트를 보여줘서 재미 요소를 더했다.
따라서 제공되는 대량의 트렌딩 플레이리스트 중 일부를 가져와 페이지를 새로고침할 때마다 random index를 골라 매번 다른 플레이리스트를 보여줄 수 있도록 했다.
const randomIndex = Math.floor(Math.random() * featuredPlaylists.length);
const selectedPlaylist = featuredPlaylists[randomIndex];