Learning by adding features to Spotify
One of the benefits of being able to develop software is that - sometimes - you can fix bugs in programs you use or add features you need to existing software. Spotify confronted me with the second situation and made me learn a multitude of programming related stuff. I'll go over the details of this process in this article.
This article is a long read. You can scroll down to the TL;DR section in which I recap the things I learned.
In the Spotify library of a user, one can find two different kinds of tracks. The first one is the more common one: a song hosted by Spotify, with a proper ID and all sorts of other meta tags. Spotify has the right to stream these songs. The second kind of tracks are so called local tracks. Those can be seen as links - or aliases - to songs that are stored on the user's hard drive. These songs are not in Spotify's repertoire and Spotify has therefore no right to stream them or store them in the cloud. However, the Spotify Player can play them on the device they were added.
I recently switched from iTunes to Spotify and was lucky enough that all the tracks I had in my iTunes library were actually available on Spotify. So instead of adding just links to local tracks, the Spotify Player recognized the - properly tagged - MP3 files as songs available on Spotify and added the songs hosted by Spotify to my Spotify library. I was able to play all the songs I had in my iTunes Library now on all my devices using Spotify.
The music business seems to be changing a lot, because obviously the songs Spotify added to my library became unavailable on Spotify eventually and they were converted to local tracks. Meaning I could only play them on the device I used to add them in the first place. A device which was not available anymore. A short search on Spotify revealed, that the songs are still available on Spotify but not as exactly the same songs. Maybe the album has changed (from the original album to a remastered one) or the original album became unavailable and the song is now only listed as part of a Best-Of album. However, most of the tracks were still available on Spotify in on or another form.
Spoiler alert: Not everything written in this article will be new to you and not everything written in this article will be best practice. This is just a story about what I learned. Since learning is a continuous process, this is not the be-all and end-all of the things covered. It's actually far from it.
In order to be able to implement the feature I needed, I had to become familiar with the Spotify API. This already taught me the first lesson. Documentation - namely a good one - is a critical feature of every software. Spotify provides the developer with a Web API Console allowing them to try out the features of the API. Sometimes however, the examples do not match with the documentation. And sometimes the example data breaks the Web Console. Things that should not happen. Also, at some point in the documentation it is stated that the Web API can handle some tasks concerning local tracks. But there are no examples which makes the feature unaccessible. There are even multiple - unanswered - issues on GitHub about that topic, which brings me to the next thing I learned: communication with other developers using your API - or other kind of software - is crucial.
fetch() writing software that connects to an API is very easy. Even Spotify's Web API's limitation of only outputting 100 tracks per request would not impose a huge problem. One could simply write a recursive function
During my research I found what would solve my problem: a NONCE. However, I had no time to implement this feature yet. Basically it's a token, only the Server and the client share with noone else knowing.
Speaking of preprocessors... I used Sass because it makes the process of nesting classes a lot easier. Also, Sass allows to play with the design in an early state of the software. With Sass one can use variables to define a color palette, font faces and other design elements that tend to change frequently in an early state. With variables, those values change once in the document and searching for each instance of that value is a thing of the past. Design-wise I wanted to make a flat UI but once I was done with it, I felt it was kind of boring. So I considered another approach: Skeuomorphic design. Quick refresher: Do you remember iOS before iOS 7? Yes? Then you remember skeuomorphic design. I always appreciated this approach and found it quite nice. Not only because you really have to craft a skeuomorphic UI. Designing a flat button is actually not hard. Designing a button that somehow feels like pressing a button once you press it, is way harder. I decided to go the - for me - hard route. While designing the UI of the software I learned about modern CSS features like the
When you look at the software over at GitHub, you might wonder "hell, this software is far from finished. It lacks proper design and the nonce is not implemented either. This brings me to my final point: I learned, that I should release early - with maybe not all features implemented - or I won't release at all. Releasing the software early as OSS also other talented and skilled developers to help the creator out. Which by the way is VERY encouraged. Open issues, fork my project and file pull requests.
Thanks for reading this post. Here's my conclusion:
Conclusion / TL;DR / Take home message
In the process of writing the software, I learned a lot about writing software in a very general term but also about language-specific topics, benefits of IDEs and how to design user interfaces.
I added a huge amount of comments to my code, documenting how things are done and what the code does. This does not only help myself when I review the code later on but also contributors who want to improve my software.
Knowing how paralyzing it can be when there are no responses to your questions confirmed me in my thinking that communication with other developers is a crucial tool to make your software accessible to more users.
Type hinting is a great tool to improve the readability of code.
Sass enables a developer to easily prototype the design of a software because of variables.
Skeuomorphic design is harder (but in my opinion more beautiful when done right) and requires you to think about your design more.
Release early or you might not release at all.