2017-10-12 11 views
0

Voici mon problème:
Spotify ne retourne pas toutes les pistes sauvegardées par l'utilisateur. Il y a une limite pour le nombre de pistes retournées - 50 (ici API).Demande multiple en guzzle


J'ai trouvé une solution qui retourne toutes les pistes enregistrées de l'utilisateur (boucle utilisée). Il fait beaucoup de demandes (dans mon cas était ~ 17 fois - 814 pistes) Mais ma page se charge de 6 secondes à 8 secondes.


Je l'ai lu Concurrent requests mais je ne sais pas comment utiliser cela et demandes async dans ma situation parce que dans mon cas, aucun montant connu des demandes. La boucle se termine uniquement lorsque le nombre de pistes retournées (items) est 0. Pouvez-vous m'aider avec mon problème?

<?php 

namespace AppBundle\Service; 

use GuzzleHttp\Client; 
use GuzzleHttp\Exception\RequestException; 
use HWI\Bundle\OAuthBundle\Security\Core\Authentication\Token\OAuthToken; 
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 

class SpotifyRequester 
{ 
    protected $client; 

    protected $tokenStorage; 

    public function __construct(TokenStorageInterface $tokenStorage) 
    { 
     $this->tokenStorage = $tokenStorage; 
     $this->client = new Client(); 
    } 

    public function getSavedTracks() 
    { 
     $token = $this->getToken(); // true token 

     $offset = 0; 
     do { 
      $response = $this->client->request('GET', 
       'https://api.spotify.com/v1/me/tracks?limit=50&offset=' . $offset, [ 
        'headers' => [ 
         'Authorization:' => 'Bearer ' . $token, 
         'Accept:' => 'application/json', 
         'Content-Type:' => 'application/json', 
        ] 
       ]); 
      // Response from current request 
      $content = json_decode($response->getBody()->getContents(), true); 
      $offset += count($content['items']); 
     } 
     while (count($content['items']) != 0); 
     // Count of tracks 
     return $offset; 
    } 
} 
+0

Comme un travail autour de vous pourrait utiliser (si Spotify n'a pas de points d'extrémité pour exposer les compteurs) une requête initiale (peut-être une limite à un enregistrement?) Cela retournera le nombre total dans le json. à partir de là, vous pouvez calculer le nombre de demandes nécessaires en fonction du nombre total et du nombre de pages nécessaires pour tout afficher. –

Répondre

1

Ne comptez pas sur cette condition. Soit compter sur l'entrée next ne pas être null ou compter le nombre total d'entrées que vous avez et le comparer à l'entrée total.


Spotify expose un certain nombre total d'entrées dans l'emballage de la réponse dans la pagination. Vous pouvez faire une première demande avec les 50 premières entrées, puis faire des demandes simultanées pour tous les morceaux restants, parce que vous connaissez le nombre total à ce moment-là.

Vous devez utiliser asyncRequest() pour les autres demandes, ce qui renvoie une promesse, et planifier toutes vos demandes restantes. Ensuite, vous pouvez attendre les promesses de manière séquentielle en utilisant la méthode d'instance wait(). L'ordre de vos appels wait() n'a pas d'importance, car wait() cochera la boucle d'événement interne et progressera pour l'une de vos demandes. Tous les autres appels wait() prennent de toute façon plus court à exécuter ou même résoudre immédiatement.

Malheureusement, vous devrez construire les URL manuellement, au lieu de pouvoir compter sur l'entrée next pour vos URL.

Je recommande d'ajouter une limite de concurrence, Spotify a probablement quelques lignes directrices pour cela. Guzzle propose une implémentation Pool pour cela.