오늘은 자신의 플레이 리스트를 구현한 방법에 대해서 적어보려고 한다. 저번에 플레이어를 실행시킨 것에 이어서 플레이어에서 알고 보니 자체적으로 좋아요 기능도 제공을 해주길래 좋아요를 눌러본 결과 어떤 에러도 발생하지 않고 실제 spotify 공식 사이트를 들어가서도 확인해 본 결과 정상적으로 추가된 것을 확인할 수 있었다. 그래서 당연히 Spotify에서 좋아요 표시한 리스트를 가져오는 API를 제공해 주겠구나 생각했지만 괜한 기대였다.
실제 좋아요 누른 목록들을 자체적으로 제공해 주지 않기 때문에 내가 생각해낸 방법은 플레이 리스트를 만들고 이 목록들을 내가 만들고 있는 웹에서 좋아요 목록처럼 사용하자는 것이다. Playlists에 대한 API의 종류가 정말 다양하다. 내가 지금 필요한 건 나의 플레이 리스트에 대한 정보이기 때문에 Get Current User's Playlists(사용자 플레이 리스트에 대한 정보)와 GetPlaylist(사용자 플레이 리스트 노래에 대한 정보)다.
Get Current User's Playlists에 대해 요청한 데이터에 일부인데 items 배열 안에 각 플레이 리스트에 대한 정보가 담겨있다. 내 플레이리스트 #1가 실제로 내가 생성한 플레이 리스트이고 다른 하나는 기본적으로 원래 있는 default 리스트다. GetPlaylist를 얻기 위해서는 플레이리스트 Id가 필요하기 때문에 요청한 데이터에서 const playlistId = data?.items[0].id; 이런 식으로 id: '2mbiqSrZfZdV0U6PaURBMr' 값을 얻어 왔다.
items: [
{
collaborative: false,
description: '',
external_urls: [Object],
href: 'https://api.spotify.com/v1/playlists/2mbiqSrZfZdV0U6PaURBMr',
id: '2mbiqSrZfZdV0U6PaURBMr',
images: [Array],
name: '내 플레이리스트 #1',
owner: [Object],
primary_color: null,
public: true,
snapshot_id: 'AAAACRa6Ccf0ZGxE6PWK5NCd027uaCxQ',
tracks: [Object],
type: 'playlist',
uri: 'spotify:playlist:2mbiqSrZfZdV0U6PaURBMr'
},
{
collaborative: false,
description: 'A playlist for testing pourposes',
external_urls: [Object],
href: 'https://api.spotify.com/v1/playlists/3cEYpjA9oz9GiPac4AsH4n',
id: '3cEYpjA9oz9GiPac4AsH4n',
images: [Array],
name: 'Spotify Web API Testing playlist',
owner: [Object],
primary_color: null,
public: true,
snapshot_id: 'AAAAEur2+1I6iINI0+04uFfVLiVJraUQ',
tracks: [Object],
type: 'playlist',
uri: 'spotify:playlist:3cEYpjA9oz9GiPac4AsH4n'
}
]
이어서 이 플레이리스트 Id를 이용하여 https://api.spotify.com/v1/playlists/${playlistId}
에 데이터를 요청한다. 여기서 나오는 데이터의 구조가 은근 헷갈리기 때문에 아래처럼 필요한 데이터를 선택해서 받아왔다.
const data = await response.json();
const tracks = data.tracks.items.map((track: any) => track);
return tracks.map(
(item: {
track: {
name: string;
uri: string;
artists: [{ name: string }];
album: { images: [{ url: string }]; name: string };
duration_ms: number;
};
}) => {
return {
songName: item.track.name,
uri: item.track.uri,
artistName: item.track.artists[0].name,
albumName: item.track.album.name,
imageUrl: item.track.album.images[0].url,
duration: item.track.duration_ms,
};
}
);
실제 구현한 사진인데 전체적으로는 서버 컴포넌트에서 실행이 되지만 아래 빨간 박스 부분은 'use client'를 사용하여 클라이언트 컴포넌트로 따로 처리했다. 왜냐하면 노래 목록을 클릭했을 때 노래에 해당하는 uri가 플레이어에 필요하기 때문에 onClick 속성을 사용하기 위해서다.
플레이 리스트, 토큰, uri 데이터를 서버 컴포넌트에서 데이터를 얻어와서 props로 전달해 주었는데 client 부분이기 때문에 따로 데이터를 가져와야 하는 건가 생각이 들었다. 공식 문서를 찾아본 결과 서버 컴포넌트에서 데이터를 가져오는 경우 클라이언트 컴포넌트로 데이터를 전달하려고 하는 경우가 있을 텐데 서버에서 클라이언트 컴포넌트로 전달된 props는 React에서 직렬화할 수 있어야 한다는 내용이다. 즉, 전달해서 사용하는 것은 문제가 되지 않는다는 말로 이해했다.