DEV Community

Cover image for Usando o spotify-web-sdk para gerenciar requisições à API Web do Spotify
Robson Junior for OpenDevUFCG

Posted on • Originally published at dev.to

Usando o spotify-web-sdk para gerenciar requisições à API Web do Spotify

Eu e Renan temos uma organização open source chamada Call Us What You Want, na qual desenvolvemos aplicações com foco em música. Um de nossos projetos é um SDK para a API Web do Spotify, que criamos para servir de apoio para outras aplicações que fazem uso desses dados.

Nessa postagem (que é tradução de uma feita originalmente no dev.to da nossa organização), vou mostrar como o spotify-web-sdk pode facilitar a recuperação e a gerência de dados de usuários do Spotify. Farei isso descrevendo o processo de desenvolvimento de uma aplicação inspirada por um problema muito sério que eu enfrentava como usuário dessa plataforma de streaming.

GitHub logo calluswhatyouwant / spotify-web-sdk

A JS SDK for the Spotify Web API.

Spotify Web SDK

A JavaScript SDK for the Spotify Web API Note that this project is still a BETA version.

Table of Contents

Features

"Why should I use this?"

We want to handle the hard work for you Even to make simple requests, such as to get information on a track, you'd need to make a bunch of setups Here is how you could do the same thing with our aid:

import * as spotify from 'spotify-web-sdk';
spotify.init({ token: 'YOUR SPOTIFY TOKEN HERE!' }); // You should only need to run this once.
spotify.getTrack('3LOpHuEpjkL4T1Zcjhko8w'); // Or any other track id.
Enter fullscreen mode Exit fullscreen mode

Yes, it's as simple as that!

"I still think it's no hard work at all.

Um problema do mundo real (A little motivation)

A seção de álbuns da minha biblioteca do Spotify é bem desorganizada, mas não exatamente por culpa minha — na implementação do aplicativo, sempre que um single é adicionado às músicas, o mesmo também acaba aparecendo como álbum. Isso acaba sendo um problema na hora de localizar algo para ouvir, já que eu prefiro consumir álbuns do início ao fim no lugar de entrar no modo aleatório das playlists.

Screenshot de álbuns no Spotify

Comfort Crowd and People são singles, mas também aparecem na minha biblioteca como álbuns.

Pensei em uma solução simples: criei uma playlist contendo a primeira faixa de cada álbum que eu já ouvi. Ter essa playlist é muito útil para que eu também mantenha o registro do dia em que ouvi os trabalhos inteiros pela primeira vez (pelo menos quando eu lembro de adicioná-los assim que termino de escutá-los). Problema resolvido... ao menos parcialmente. Bem, para manter as coisas ainda mais organizadas, eu ainda queria poder ordenar as referências aos álbuns pelas suas datas de lançamento, algo que o Spotify ainda não dá suporte (mesmo com usuários pedindo por essa feature há mais de cinco anos).

Procurei por ferramentas que pudessem gerenciar esse método de ordenação para mim e descobri uma aplicação web chamada Sort Your Music. Apesar de ser super simples e eficiente de usar, a abordagem de ordenação deles sobrescreve a data de adição das faixas. Sei que por agora você já deve estar revirando os olhos com a minha insatisfação, mas, sabendo que é possível conseguir o resultado que eu desejo, decidi implementar a minha própria ferramenta. Nada como um pequeno "faça você mesmo", certo?

Taylor Swift com ódio

Perdoe-me caso você não enfrente esse problema no seu dia a dia.

Devagar e sempre

A API Web do Spotify disponibiliza dois endpoints para gerência de playlists: um que permite sobrescrever todas as faixas e outro que pode ser usado para mover uma faixa ou um bloco de faixas. Ao contrário do primeiro, este não modifica o timestamp que indica quando as faixas foram adicionadas à playlist e o identificador de quem as adicionou (para playlists colaborativas).

Visualização da reordenação de faixas

Visualização de como funciona o endpoint "reordenação de faixas de uma playlist".
Fonte: Spotify for Developers

Como visto acima, esse endpoint funciona de forma que ordenar uma playlist requer várias requisições consecutivas (basicamente uma requisição por faixa na playlist), o que também significa que leva muito mais tempo do que simplesmente sobrescrever tudo. Sacrifícios tiveram que ser feitos, mas o resultado é exatamente o esperado: aqui está o Spotify Playlist Editor!

Spotify Playlist Editor

Quando você tiver feito login, algo assim deve aparecer na tela inicial da aplicação.

Detalhando o processo (mas não demais)

Eu queria prototipar uma aplicação React o mais rápido possível, então usei o create-react-app, que me poupou muito tempo de configurações iniciais. Em geral, encorajo que você tente entender como criar uma aplicação React do zero, mas isso é com certeza é uma mão na roda quando se tem pressa. Para manter tudo simples, o Spotify Playlist Editor é serverless, mas permite que todos acessem seus dados do Spotify através de uma implementação do fluxo de concessão implícita, uma abordagem simples para conseguir token de acesso à API.

Incluí alguns pacotes e ferramentas para simplificar o processo de codificação (por exemplo, Bootstrap para que eu me preocupasse menos com estilos e prettier para ajudar a manter o código padronizadinho). Também considero interessante mencionar que uso Flow para checagem estática de tipos. Eu amo que JavaScript tem tipagem dinâmica, mas como o SDK lida com muitos modelos que têm, por sua vez, muitos atributos, Flow se torna um ótimo aliado.

IntelliSense

Você pode até odiar o Flow, mas o fato é que React + Flow + IntelliSense é um verdadeiro dream team.

Conheça o melhor amigo autoproclamado da API Web do Spotify, o spotify-web-sdk!

Aqui está um trecho de código tirado do componente UserPage. Você pode ver que alguns imports são feitos diretamente ao SDK:

/* @flow */

import React, { Component } from 'react';
import {
    /* Funções que encapsulam endpoints da API do Spotify */
    init,
    getCurrentUserPlaylists,
    getCurrentUserProfile,
    /* Modelos */
    Page,
    PlaylistSimplified,
    PrivateUser,
} from 'spotify-web-sdk';

type Props = {
    history: any,
};

type State = {
    page: Page<PlaylistSimplified>,
    playlists: PlaylistSimplified[],
    user: PrivateUser,
};

class UserPage extends Component<Props, State> {
    // ...
}
Enter fullscreen mode Exit fullscreen mode

Uma vez que o usuário esteja conectado ao Spotify, UserPage é a página principal da aplicação. Seu principal propósito é exibir uma lista de playlists do usuário, com um botão que permite selecionar uma playlist de interesse. Inicialmente, cinco playlists são recuperadas:

componentDidMount = async () => {
    const page = await getCurrentUserPlaylists({ limit: 5 });
    this.setState({
        page,
        playlists: page.items,
    });
}
Enter fullscreen mode Exit fullscreen mode

Ao manter o objeto page no state do componente, requisitar mais playlists é tão simples quanto poderia ser. Isso é graças à lógica de recuperar os próximos dados já estar implementada lá na declaração da classe Page no spotify-web-sdk:

class Page<T> {
    // ...
    async getNextPage() {
        if (!this.hasNext()) throw new Error('There are no more pages');
        const params = {
            ...this.queryParams,
            limit: this.limit,
            offset: this.offset + this.limit,
        };
        const response = await this.getAxiosPageInstance().get('/', { params });
            return new Page<T>(response.data, this.t, this.wrapper);
    }
}
Enter fullscreen mode Exit fullscreen mode

Dessa forma, lidar com toda essa lógica no editor de playlists se resume a uma simples chamada de função, dispensando a necessidade de manter-se a par de valores como limite e offset:

loadMorePlaylists = async () => {
    const { page } = this.state;
    const nextPage = await page.getNextPage(); 
    // Relaxa e deixa o spotify-web-sdk lidar com o trabalho duro!
    this.setState(prevState => {
        const playlists = prevState.playlists.concat(nextPage.items);
        return { playlists, page: nextPage };
    });
};
Enter fullscreen mode Exit fullscreen mode

O propósito principal da aplicação é permitir que os usuários ordenem suas playlists, então vamos focar nisso agora. Do componente PlaylistPage, o usuário pode selecionar um método de ordenação (incluindo por data de lançamento!). Por baixo, minha implementação determina primeiro a ordem final esperada das faixas e então faz uso de chamadas sequenciais para reordená-las. É assim que funciona mais ou menos em código:

import { reorderPlaylistTracks } from 'spotify-web-sdk';

export const sortPlaylistTracksByAttribute = async (
    playlistId: string,
    attribute: string
) => {
    let insertionOrder = await getInsertionOrder(playlistId, attribute);
    return insertionOrder.reduce(async (previousPromise, current) => {
        await previousPromise;
        return moveTrackToTop(playlistId, current);
    }, Promise.resolve());
};

const getInsertionOrder = async (
    playlistId: string,
    attribute: string
) => { /* Determina a ordem de inserção baseada no atributo escolhido. */ };

const moveTrackToTop = (id: string, oldIndex: number) =>
    reorderPlaylistTracks(id, oldIndex, { rangeLength: 1, insertBefore: 0 });
Enter fullscreen mode Exit fullscreen mode

A propósito, se você não está familizarizado com essa abordagem de resolver Promises sequencialmente usando Array.prototype.reduce(), tem um excelente artigo explicando como e, mais importantemente, a razão disso funcionar. Dá uma olhada lá no CSS Tricks!

Como mostrado acima, o objetivo principal do spotify-web-sdk é poupar tempo dos desenvolvedores que desejam fazer acesso à API Web do Spotify. No lugar de fazer chamadas diretas à API e se preocupar com detalhes, a maior parte do seu trabalho deve ser importar uma função e invocá-la no código.

Caso você tenha interesse em construir sua própria aplicação usando dados do Spotify, a versão atual do spotify-web-sdk está hospedada no NPM e pode ser adicionada rapidamente em um projeto com package.json rodando npm add spotify-web-sdk.

O Spotify Playlist Editor também está no ar aqui se você quiser brincar um pouco. Caso você experiencie qualquer coisa inesperada ao usar a aplicação, é apenas um treino para estimular o espírito open source: crie uma issue no repositório do GitHub! PRs também são sempre bem-vindas (tem umas issues abertas e o Hacktoberfest está logo aí...).

GitHub logo calluswhatyouwant / spotify-playlist-editor

Sort your Spotify playlists any way you want.

Spotify Playlist Editor

Sort your Spotify playlists anyway you want! 🛠

Initial page

Table of Contents

Features

  • Create new playlists out of your recent Spotify tracks or your all-time top tracks;
  • Sort playlists based on
    • playlist track attributes (addition date);
    • track attributes (name, length, popularity);
    • album attributes (name, release date);
    • artist attributes (name).

Current limitations

  • It's highly recommended to create a copy of the playlists you want to edit or to use one of the playlist creation options. (play around, but do it safely!);
  • You can only sort playlists with 100 tracks or less;
  • Sorting might take a while (a playlist with 100 tracks can take between 30 seconds and 1 minute). Do NOT reload or close the playlist page until sorting is over.

Community

Installation and Usage

Simply run yarn install to install the project's dependencies…

Se quiser ficar por dentro das novidades dos projetos do Call Us What You Want, acompanhe o nosso perfil no Twitter!


Muito obrigado pela leitura! Fique atento: em breve, teremos novos artigos de contribuidores do OpenDevUFCG aqui no dev.to. Acompanhe o OpenDevUFCG no Twitter, no Instagram e, claro, no GitHub.

Discussion (1)

Collapse
thayannevls profile image
Thayanne Luiza

Tinha lido em inglês, em português está ainda melhor ❤❤❤❤