Blog

Get Your Front End On - A Guest Blog Post by Andrew Baldock

Written by Terence Bennett | December 16, 2013

Andrew is a Frontend Engineer in San Francisco. He recently built an application called Skylab FM, a single-page application that uses RequireJS, BackboneJS, the SoundCloud API, and DreamFactory on the backend. In this guest blog post, Andrew walks you through how he built his app without writing any server-side code. 



Here's Andrew.

With screens of all shape and size falling out of our pockets, it's a renaissance age for interface builders. Everything is being made clickable and touchable. Everything needs a frontend to interact with users.

Frontend developers have more muscle than ever at their fingertips. JavaScript developers now have client-side frameworks such as Backbone, Angular and Ember to provide sanity-maintaining MVC structure and robust, modular patterns of development that even seasoned veterans of other languages will respect. Even the saltiest server-side developers are taking a fresh look at what's going on in the frontend.

Getting Started

Recently I wanted to level up, to give myself a challenge and try out BackboneJS for the first time. I chose Backbone with the idea that the “least opinionated” of the modern data-binding toolkits would be a reasonable trailhead. I also knew I wanted to use RequireJS for module and dependency loading.

The documentation for RequireJS points to an application seed wired up to demonstrate how to ‘Require' jQuery from a content delivery network. I'm all for loading fonts, libraries, etc. from CDNs so this seemed like a great place to start. To see for yourself, check out this example of using require.js to load jQuery from a CDN.

TIP: Start with an app seed. An app seed is an excellent way to see just how to begin the first gossamer wisps of your new masterpiece. Light packages that capture the very beginning vanilla structure of an application, they are a great place to see just how to wire up the first few bits. Try going to GitHub or Google and searching for “app seed” plus the technology of your choice.

What to Build?

Now I have a foundation to build on…but what to build? I enjoy finding new music on SoundCloud, and their API is well-documented, so I thought that building an alternate presentation of their library -- a sort of SoundCloud musical discovery app, could be fun.

I also wanted to try my hand at saving state. If you've used Pandora, you know that it takes a search input and makes a "station" out of it -- a clickable reference in the interface that represents the resulting songs found by the search, so the user can return to their stations on any browser or device. So putting it all together, I decided to try my hand at a Pandora-like “listening lounge” using SoundCloud as the source music library, where people can return to their previous searches.

Here’s an overview of how the application works.

So what will this Soundcloud satellite do?

The app takes a search input and makes a "station" out of it -- a clickable reference in the interface that represents the resulting songs found by the search.

1.  User enters a search

2.  

Search is performed on Soundcloud database

3.  

Soundcloud results are displayed to the user

4.  Search is saved to a database

5.  Search is displayed back to the user

Following an App Seed I assembled a single page web application to handle (1), (2) and (3).

Now I just need to figure out (4) and (5), the database piece! Keep reading to see how.

NOTE: the finished code of version one of the skylab fm application is available on GitHub as a companion repository for this article. Please clone or fork the repo and see how the code works!

How to Save Data?

Great, now I've got my requirements, my libraries, my starter app all set! But wait...there's that requirement about saving state. How do I “save” state in my application, so that a user can return to the app and restore it to how they left it? Here's where I need a backend, with a database, naturally.

This is the point at which I start building out a backend. But I really just want to wear my frontend hat, so I can focus on learning Backbone and Require. Wouldn't it be cool if there were a free cloud-hosted database with a REST API that I could "just use"?

I didn't even know if such a thing existed, but I thought it might, so I did a Google Search on free rest api backend.

Enter DreamFactory

One of the first links was DreamFactory. It's a very cool name, but I quickly discovered that it's actually a nifty free service that offers exactly, to the letter, what I was hoping to find. Friends, gather 'round, because this is what I'm here to tell you about. There is a magical backend in the clouds. A place where:

  • There's zero backend code to write

  • You can walk up and within minutes start reading and writing data to your database via REST calls

  • The REST API for this database has guided, interactive docs that help you build and test your ajax URLs

  • Set up is streamlined to the fewest clicks possible

Get Set Up on DreamFactory

Once I found DreamFactory, it took a single sign up to get access to exactly the backend I needed. Within 20 minutes I had navigated the admin areas of my new free hosted backend, started a new Single Page Application within it, created a database for it, and granted authorization rights for my own website's domain.

With these simple steps you can have a DreamFactory backend in 10-30 minutes depending on your deadline and/or current state of caffeination. Let's walk through that process.

  • Sign Up. The easiest way to get started is to sign up for a free hosted account on dreamfactory.com. DreamFactory is an Apache open source software package, so alternatively you can install it on your own Linux Server, AWS, Azure, Rackspace, VMWare, or locally on your computer. If you want to do that go to the DreamFactory listing on Bitnami and use the Bitnami one-click installer. This blog post shows you how to install Dreamfactory on AWS.

  • Create a DSP. In my Dreamfactory Dashboard I created a free Dreamfactory Services Platform (DSP)

  • Launch your DSP and follow the prompts in the QuickStart tab. You’ll be asked to name the app you are creating, and whether it's a web or native app (in my case it's a web app). When asked where I would keep my code for the App, I chose to develop my code locally. You can also store and edit your code right in the DSP interface if you prefer. 

  • Get the SDK. At this point you can download a software development kit that is wired up to your settings and your API key. It will be named after your site and have all the starter code you need to get up and running. You can use this SDK as your very own app seed, or at least use it to see what talking back and forth to the database from your local code will look like. I highly recommend downloading the SDK and playing with it! Note that use of this SDK on the local file system requires "*" (an asterisk) to be in your list of allowed hosts in the CORS configuration section of the DSP Admin Console. This screencast shows how to get started with the SDK.

My Own Use of DreamFactory

There are a lot of options and features in the DSP that I have not yet touched — here's what I did to get a database up and running for my app as I needed it.

Since the code for my app has a password in it to get token access to the DreamFactory database, I wanted to make sure that one account has as little access as possible but would give me a token back.

  • In the Users tab, I created a user called ‘systemuser', and manually assigned the password. I did NOT check ‘This is a System Administrator'.

  • In the Roles tab, I created a new role called 'systemrole', assigned my systemuser from above to this role, then assigned my app to this role, and finally assigned Service Access to this role - all/full access. NOTE: This was a quick and dirty way for me to get data storing in a database for a demo app that I could distribute, and probably not the most secure setup ever invented; however it suits my needs because with CORS I can limit access to just whitelisted domains. The SDK that you can download from the DSP Admin Console shows an even more secure way to authenticate.

  • In the Config tab of the DSP Admin Console, under CORS Access add an asterisk “*” in your list of allowed hosts. This is for while you initially develop, you will want to set this to be more secure later.

Hark, a Database!

In the Schema tab of the DSP Admin Console, I created a table, ‘searches', with the following fields: id, userid, and search. This table serves the current backend datastore for the demo app you can download from https://github.com/andrewbaldock/skylabfm-demo.

API and Interactive Docs

You might want to spend some time perusing the sample apps DreamFactory loads inside the DSP for you to look at. Another feature I found insanely useful was the interactive REST URL builder / documentation powered by Swagger. This piece is especially nice as it helps you construct the URLs you will put into your own frontend code. Find this tool under the API/SDK tab.

Show Me the Codes

“That sounds great Andrew, but we're like halfway through this blog post and so far haven't seen any code snippets. Don't we need code snippets?”

Yes. Yes we do.

A Backbone Model for the DreamFactory Token

To manage getting a token from DreamFactory which I can use to authenticate every future request in the session, I use a Backbone Model to store the token, and to pass the token to other parts of my application via events.

var DfAuth = Backbone.Model.extend({

 /* DreamFactory Authentication module
  * uses a backbone model as a settings singleton to hold session info
  * ----------------------------------------------------------------- */

 // CONFIG: YOU should update baseurl and apikey to match your DSP.

 defaults: {
   baseurl:    'https://dsp-skylabfm-demo.cloud.dreamfactory.com/rest',
   apikey:     'skylabfm-demo',
   sessionId:  ''  // INFO: value we will get back from dreamfactory to use in future requests
 },

 initialize: function () {  
   this.sync();
   var me = this;   // to save scope
   setInterval(function(){
     me.sync();
   },600000);       // 10 minutes -- keeps the session alive in the browser by refreshing token
 },

 sync: function() {
   var me = this; 
   $.ajax({
     type: "POST",
     url: this.get('baseurl') + '/user/session?app_name=' + this.get('apikey'),
     dataType: "json",
     contentType: "application/json",
     data: JSON.stringify({email:'system-user-you-created@gmail.com',password:'password-you-made'}),
     /* CONFIG: put your system user info above...if you want to go this route.
      * Here I am using a special "system user" I set up in my dreamfactory.com dsp.
      * This System User is barely-privileged to grant dreamfactory api authentication
      * only; which is why I'm not stressed out about having this password exposed in 
      * code here.  YMMV.
      * -----------------------------------------------------------------------------*/ 

     success: function (response) {
       me.set({sessionId:response.session_id});
       me.trigger("dreamfactory: authenticated", me);                 },

     error: function (response, textStatus, xError) {
       console.log(response.responseText);
       $('#spinner').hide();
     }

   });
  }

});

There are two things worth noting here. One, I'm using a setInterval in the initialize() function to handle getting a token every so often to keep the page authenticated to the backend. Two, with each successful token refresh, I am triggering a 'dreamfactory:authenticated' event which carries the new token inside it. Other bits of the application that talk to the DreamFactory backend and need a refreshed token get it automatically by listening for these 'fresh token' events.

Backbone Collection and DreamFactory Database

To save and retrieve a user's searches, I use a Backbone collection:

var Searches = Backbone.Collection.extend({

 initialize: function () { // fires at creation.
  this.model = new SearchModel();
 },

 setup: function(auth){
  this.auth = auth;
  $.ajaxSetup({ headers: {
   'X-DreamFactory-Session-Token': auth.sessionId,
   'X-DreamFactory-Application-Name': auth.apikey
  }});
  this.model.setup(auth);

  // CUSTOMIZE: YOU should customize this URL to match your Dreamfactory DSP needs
  this.url = auth.baseurl + "/db/searches?filter=userid%3D'" + auth.userid + "'&fields=id,query";
 },

 parse: function(data) {
  _.each(data.record, function(search) {
   var model = new SearchModel({id:search.id, query:search.query});
   model.setup(this.auth);
   this.add(model);
  }, this);
 },

});

Backbone Model and DreamFactory Database

And finally, at the heart of the user search, here is the Backbone model representing a single search query -- in other words, a single row in my backend database.

return Backbone.Model.extend({

 initialize: function(auth) { // fires at creation.
  if(auth)
   this.setup(auth)
 },

 setup: function(auth) {
  // NOTE: github.com/jashkenas/backbone/issues/789
  var idFix = (this.has("id") ? "/" + this.get("id") : "");

  // CUSTOMIZE: YOU should customize this URL to match your Dreamfactory DSP needs
  this.url = auth.baseurl + "/db/searches" + idFix;
 },

 defaults: {
  userid: '',
  query: ''
 }

});

...Go See the Code for Yourself

A Github repo with all the code described in this post is available for you to fork or clone at: https://github.com/andrewbaldock/skylabfm-demo

The Rise of SkyLab FM

And then the coolest thing happened. Suddenly I was reading and writing data from my own website code, to this new backend on Dreamfactory.

Sure, there's a never-ending list of improvements to do on my app -- it badly needs a thumbs up and down system, and I should allow for other ways to authenticate. For now though, it's fun to play with - you can go use it today, and feel free to grab the code.

Go Forth and Build

So if you've ever thought about what it might look like to build yourself a single-page-app, or have done so but want to try it again with other technologies, it's a great time to jump in. Frameworks are providing structure, there are lots of APIs out there to explore, and it's so very easy to wire up a backend from Dreamfactory. Now my friends, lets get out there and build the world!

Andrew Baldock is a Frontend Engineer at Connect Solutions in San Francisco.