Spotify api 사용기

문강현·2026년 4월 9일
post-thumbnail

시작하며

이번 글에선 Spotify api를 사용하면서 어떤일이 일어났는지 또 어떻게 해결했는지 그리고 기본적인 사용법에 대해서 간단하게 적어 보겠습니다.

사용법

앱 생성하기

먼저 Spotify api를 사용 하려면 앱을 생성해야합니다.
앱은 아래 보이는 링크인 spotify for developer 에서 생성할 수 있습니다.
https://developer.spotify.com

이런식으로 dashboard에 들어가서 앱을 생성할 수 있습니다.
앱을 생성할 때 앱 이름, 앱 설명, 웹사이트(필수 아님), 리디렉션 URL과 같은 정보들이 들어가게 됩니다

앱을 생성 하면 이런식으로 Dashboard에 내가 생성한 앱이 뜹니다.
그리고 앱을 클릭하면 자신의 앱 정보와 client id, client secret 이 나오게 됩니다.
이것을 환경 변수에 넣거나 하드 코딩해서 api를 불러와서 쓸 수 있습니다.

주요 기능

검색

트랙, 아티스트, 앨범, 플레이리스트 등을 키워드로 검색할 수 있습니다.

GET https://api.spotify.com/v1/search?q={검색어}&type=track,artist,album

트랙 정보

특정 트랙의 제목, 아티스트, 앨범, 30초 미리듣기 URL, 커버 이미지 등을 가져올 수 있습니다.

GET https://api.spotify.com/v1/tracks/{track_id}

아티스트 정보

아티스트의 이름, 인기도(popularity) 등을 가져올 수 있습니다.

GET https://api.spotify.com/v1/artists/{artist_id}
GET https://api.spotify.com/v1/artists/{artist_id}/top-tracks

앨범 정보

앨범에 포함된 트랙 목록, 발매일, 커버 이미지 등을 가져올 수 있습니다.

GET https://api.spotify.com/v1/albums/{album_id}

플레이리스트

공개된 플레이리스트의 트랙 목록을 가져올 수 있습니다.

GET https://api.spotify.com/v1/playlists/{playlist_id}/tracks

실제 사용기

저는 디코봇에서 !노추 !가수 와 같은 키워드로 노래 추천과 가수를 검색하는 기능을 구현하였고 또한 디코봇을 만드는 여러 방법 중에서 discord.js라는 라이브러리를 이용하여 작업하였습니다.

Access Token 발급

위에서 설명했던 Spotify Api 앱 생성에서 받았던 client_id와 client_scret을 사용해야 합니다.
저는 유저 로그인이 필요 없는 Client Credentials Flow 방식을 사용했습니다.

async function getAccessToken() {
  const credentials = Buffer.from(
    `${process.env.SPOTIFY_CLIENT_ID}:${process.env.SPOTIFY_CLIENT_SECRET}`
  ).toString("base64");

  const response = await fetch("https://accounts.spotify.com/api/token", {
    method: "POST",
    headers: {
      Authorization: `Basic ${credentials}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: "grant_type=client_credentials",
  });

  const data = await response.json();
  return data.access_token;
}

토큰은 발급 후 약 1시간(3600초) 뒤에 만료되기 때문에, 매 요청마다 새로 발급받는 건 비효율적입니다.
그래서 토큰을 캐싱해두고 만료됐을 때만 새로 발급받는 방식으로 구현했습니다.

let cachedToken = null;
let tokenExpiresAt = 0;

async function getToken() {
  if (cachedToken && Date.now() < tokenExpiresAt) {
    return cachedToken;
  }
  const token = await getAccessToken();
  cachedToken = token;
  tokenExpiresAt = Date.now() + 3500 * 1000; // 여유 있게 3500초
  return token;
}

장르 검색 기능

처음에는 장르 검색 기능을 Spotify API의 기본 기능을 활용하여 구현하려고 했습니다.
하지만 확인해보니 API에서 장르 기반 검색을 직접 지원하지 않는다는 것을 알게 되었습니다.

물론 artist_id를 활용하여 간접적으로 구현할 수는 있었지만 이 방식은 구조가 복잡하고 실제로는 장르가 아닌 곡 제목 기반 검색으로 동작하는 문제가 있었습니다.
예를 들어 !노추 힙합과 같이 검색하면 장르와는 무관하게 “hip-hop”이라는 제목의 노래가 검색되는 이슈가 발생했습니다.

이 문제를 해결하기 위해, 클로드가 제안 해준 것을 참고하여 장르별 아티스트를 직접 정의하는 방식을 선택했습니다.

const GENRE_ARTISTS = {
  케이팝: ["BTS", "아이유", "NewJeans", "BLACKPINK", ...],: ["Taylor Swift", "Ariana Grande", ...],
  힙합: ["Travis Scott", "빈지노", ...],
  // ...
};

이처럼 장르별로 아티스트를 하드코딩한 뒤,
예를 들어 !노추 인디와 같이 입력하면 해당 배열에 포함된 아티스트(검정치마, 잔나비 등)의 음악을 검색하는 방식으로 구현했습니다.

이 방법을 통해 장르 검색 기능의 문제는 해결할 수 있었지만,
등록된 아티스트에만 의존해야 한다는 한계가 있어 추천 범위가 제한적이라는 단점이 있습니다.

추후에 더 고민해보고 더 나은 방향이 있으면 수정할 예정입니다.

구독 문제

처음 앱을 생성하여 코드를 짜고 개인 서버에서 요청을 보냈는데 어떻게 해도 계속 오류가 떴습니다.
저는 Spotify API를 무료 버전에서도 사용할 수 있을 것이라고 생각했지만 유료 구독이 필요했습니다. 따라서 아직 사용하지 않았던 3개월 무료 체험을 통해 구독을 진행했습니다.

하지만 또 다른 문제가 발생했습니다. 콘솔에서 유료 구독 정보가 서버에 반영되기까지 몇 시간이 소요될 수 있다는 메시지가 표시되었고 약 2시간 정도 기다렸음에도 정상적으로 적용되지 않았습니다.

따라서 해결하기 위해 기존에 생성했던 앱을 삭제하고 새로 생성하려 했지만 앱을 다시 만들기 위해서는 24시간을 기다려야 한다는 제한이 있어 예상보다 많은 시간을 소모하게 되었습니다.

limit 에러

처음에 limit을 20으로 설정했는데 계속 400 에러가 났습니다.
알고보니 Client Credentials 방식의 앱은 limit을 10 이하로만 설정해야 했습니다.
공식 문서에는 명확하게 나와있지 않아서 찾는 데 시간이 걸렸습니다.

// Client Credentials에서는 에러 발생
limit: 20

// 10 이하로 설정해야 정상 동작
limit: 10

URL 인코딩 문제

처음에는 Node.js의 https 모듈을 직접 사용해서 API를 호출했습니다.
그런데 검색어에 한글이나 특수문자가 들어가면 URL 인코딩이 제대로 되지 않아 요청이 실패하는 문제가 있었습니다.
해결 방법은 클로드가 제안 해주었습니다.
https 모듈 대신 Node.js 18+에 내장된 fetch를 사용하고,
URLSearchParams로 쿼리를 구성하면 인코딩을 자동으로 처리해줍니다.

// 인코딩 문제 발생 가능
const url = `https://api.spotify.com/v1/search?q=${query}&type=track&limit=20`;

// URLSearchParams로 안전하게 처리
const params = new URLSearchParams({ q: query, type: "track", limit: 10 });
const url = `https://api.spotify.com/v1/search?${params}`;

마치며

Spotify API 자체는 문서도 잘 되어있고 사용하기 어렵지 않았지만, 처음 사용해보기도 하고 여러 시행착오가 많았던 것 같습니다.
그래도 좋은 경험 이었던 것 같고 앞으로도 이런 새로운 시도를 많이 해보고 싶습니다!!
글 읽어주셔서 감사합니다.

0개의 댓글