title: Spotify Metadata API: Search By Artist
body: <p>The original plan was to write this as a blog post, entitled "Inefficiencies in the Spotify Metadata API : Or, How the Jackson 5 killed my Browser", but changed my mind at the last minute as I have a habit of missing the obvious in documentation,perhaps an undocumented feature might exist which I have missed, or someone else has solved the issue - so hence this question has a certain blog-post tone about it!</p>
  
  <p>I am developing a small web-app, mostly for a small group of people, which will allow anyone to update a Spotify playlist. As not everyone has Spotify (though I don't know why!), the page will update a database with songs, as App running in Spotify on my laptop polls the database for updates, then using the Spotify Apps API, the playlist is updated, and anyone subscribing to the playlist gets the update. This is ok, though I would like to use push rather than poll, but that's a topic for another day. </p>
  
  <p>I searched around for a Javascript library to use with the Spotify Metadata API, and found one (<a href="https://github.com/palmerj3/SpotifyJS" rel="nofollow">https://github.com/palmerj3/SpotifyJS</a>) though it was basically a wrapper and still required you to parse the JSON yourself. Thinking I could go one better and put some basic parsing in for the most common fields (title, artist, album, Spotify URI) I started working on my own library/JQuery plugin.</p>
  
  <p>Search by track is not a problem, it's a single call to the spotify metadata API, the results are easily parsed, matching the returned artist with the requested artist (if present) makes for an easy search by title/artist.</p>
  
  <p>Search by Artist (obtain a list of all songs by a particular artist) though, appears to be a pain-in-the-<em>*</em>*! As best as I can tell from the docs, this is the process.</p>
  
  <ol>
  <li>Search for the artist: this will return a list of artists which match the query</li>
  <li>For each artist, lookup their albums: this will return a list albums</li>
  <li>Lookup each album and retrieve a track list</li>
  <li>Compare the artist for each track with the search artist, if it matches output</li>
  </ol>
  
  <p>The first step will return a small list of artist matches, Foo Fighters has 2, Silverchair 1, and The Jackson 5 has 4. This small list turns into a larger number of album matches - from memory Foo Fighters returned 112, which then turns into even larger number of track lists. From a Javascript/JQuery perspective, this leads to daisy-chained AJAX request, for each step, and at each step massive numbers of, nearly concurrent GET requests against the Spotify servers. </p>
  
  <p>The initial version I wrote cheated and used synchronous AJAX, and worked ok, as each request must complete before the next would start, though, this would lock the browser up for some time, and removed the possibility of using feedback to the user that the system was running. I then switched to asynchronous requests and all hell broke loose! You immediately hit issues with rate limiting on the Spotify end, which returns resoponses with 502 bad gateway (not listed in the spotify docs as a status by the way), or 503 - both of which JQuery interpreted as status code 0 - which was interesting, requiring debugging in Firebug. I throttled the requests down on the client side, I found that 1 every second was about right, to avoid rate limiting and ensure I got a response containing data each time, however, this then causes massive lock ups in the browser as it had upwards of 30 or 40 GET requests in parallel, all returning pretty much at the same time (though some requests responded after 15+ seconds!) and then parsing all the JSON responses. </p>
  
  <p>I looked into alleviating the load by using a server-side approach, though this has downsides as well:
  1. you don't avoid the basic issue in that the API can not handle the task in an efficient manner
  2. for a busy site, the bandwidth usage will be against the server, which will also present a single IP, for multiple users you will soon hit the rate limit due to parallel users</p>
  
  <p>The server side does offer caching though which could be beneficial, to this end I found a PHP Library - metatune (<a href="https://github.com/mikaelbr/metatune" rel="nofollow">https://github.com/mikaelbr/metatune</a>) advertised as the "The ultimate PHP Wrapper for the Spotify Metadata API", but unfortunately only offers the same basic lookup/search as the Spotify Metadata API - i.e.: no listing of all songs by an artist.</p>
  
  <p>Thus, I have now disabled searching by artist, until I find a suitable solution.</p>
  
  <p>Assuming I have not missed anything, it seems, to me at least, to not be an efficient API design, as it encourages you to make large numbers of requests to the Spotify servers, which is not good for me as a client, and not good for Spotify as a server. I can't help but think that if there was a request such as:</p>
  
  <p>ws.spotify.com/search/1/artist.json?q=foo+fighters&amp;extras=tracks</p>
  
  <p>then the issues discussed here would be alleviated, a single request would cover what requires 3 sets of multiple requests currently; rate limiting wouldn't be as big an issue; the overheads to process the data on the client are greatly reduced; the overheads for Spotify to handle would be reduced and the entire service would be more efficient. The fact that the request would return a very large data set is not an issue, as the API already splits data into "pages".</p>
  
  <p>So, my questions to the crowd:
  1. Have I missed something obvious in the documentation, or is there a secret request?
  2. In the absence of an API request, does anyone have a suggestion on how to make my system more efficient?
  3. Has anyone solved this issue before?</p>
  
  <p>Thanks for reading! Took a long time to get to the questions, but I felt it necessary to provide as much reasoning to find the best solution, and also, it illustrates the deficiency in the API, which I hope someone from Spotify will notice!</p>
  
  <p>Finally as an aside, projects like this make me feel like we've swapped Flash for Javascript but the performance is still as bad! Anyone else feel the same?</p>
  
  <p>Cheers!
  sockThief</p>