For a couple weeks, I have been working on an idea that I hope will develop into something greater in the next months. While that idea involved mainly theoretical and operational issues, I wanted to keep my practical skills inline and since I have been reading a lot about web applications and especially Backbone.js, I decided to just play around with it. I ended up writing a small prototype for a Facebook Photo Browser based on the Graph API.
While the browser is not even close to something that has production value, I did learn a lot about Backbone and web applications, so I thought I might just publish the code and offer some explanation, in case it could help someone. I always love to read blogposts like this, because it offers insights in what the programmer thought of. There is more to programming than just the lines of code. The code is on Github and the demo runs here.
I should probably start and excuse myself for the poor structure and documentation of the code. In a lot of ways, this is typical chaotic spaghetti-code. Although I tried to have some architecture to it so that it can be extended later, especially in the later stages of the prototype, it becomes evident that careful planning and enduring discipline is needed to create great web applications.
The web application is your typical one-page page web app. The idea behind it was to think of alternative interfaces for Facebook's rich data. Therefore I got rid of all other distracting information, no page reloads, ajaxified, fluent navigation. I also implemented a rest-style history, so that you can go back to any pointer and the state is preserved.
Overview of the Software stack
The software stack of the application is relatively simple: Node.js on the backend, Backbone.js/jQuery on the frontend. With Node.js, I use node-static to simply serve our files statically. For production use, something more like connect would probably better to have gzip compression, or just move it to a CDN completely since we just have static files. I also recommend using Heroku for deployment. With the new Cedar stack, it is dead easy and fast to deploy a Node.js application for free. The backend is just this code:
While the code itself is sparsely commented, I will try to explain some of the rationale behind the prototype. First, I decided to have a small loading screen to init the Facebook SDK. The logic is in the bootstrapping object in /public/app.js:
We then load the Facebook SDK asynchronously and bind the proper events to detect a login. Once we successfully logged in, we remove the splash screen, create our app object and start the history object. The application itself is divided into a toolbar to display loading messages as well as providing links to the users newsfeed and profile. The presentation of the photos is divided into what I called mainpane, which holds collections of items and a viewer which displays a single item. I always ended up implementing a fullscreen view.
Those higher-level objects have a addModel function that takes an object and tries to properly display it based on eitheir the main objects modelmap, or the view that is attached to the model in case of mainpane models. It would have been probably more Backbone-style, if I had implemented that with events.
Example flow of the Application
After the Application initialized, Backbone handles the routing. So our default route is to load the newsfeed:
We create a new instance of the Feed model, bind some events to show the loading of the model, initiate the fetching of the object and add it to our mainpane. We also add null to the viewer to ensure that the mainpane has the full screen estate.
Add a model to the Mainpane
Again, this code is pretty simple: Remove the previous model's view, set the new model, and create a new view and append it to the mainpane's element.
Fetching Objects from the Graph API
The nice thing about Backbone is that it forces you to think in structural reusable patterns. Since Facebook's Graph API is not strictly RESTful, we have to modify the sync and parse functions of the Feed Object. The sync function is in charge of doing the actual call to the API:
Since Facebook again does not do it the RESTful way, we also have to modify the parse function to parse our response:
Displaying a Collection
The collection view that we appended to the mainpane earlier listens for "add" events of the Feed Collection to add items to the view:
I use jQuery Masonry to display individual items since it is very flexible with resizing, so we have to update it every time we insert a new item.
Displaying a single item
We can trigger the display of single item like this: We add the Photo model to the viewer, create a point in the history, and save the state of the application.
The viewer handles the model, based on its current state to display it:
There are more aspects to this application, but unfortunately, I have not enough time to follow up to this prototype. If there is enough demand, I might elaborate on the other aspects.