I’ve been doing scripting to some degree throughout my career, but rarely more than a simple script to accomplish a repetitive task. When I started at SolidFire I decided I needed to up my game, considering the entire product is built around API configuration and management.

Like many from the infrastructure side I chose Python to get started. I’d used Python before, but it had been a while and I’d forgotten most of the language. Luckily I came across the Python Fundamentals and Python - Beyond the Basics courses on Pluralsight by Austin Bingham and Robert Smallshire. While not necessarily targeted for the absolute beginner, these are fantastic courses that throughly cover the details of the language. With that and a bit of Googling, I was soon writing metaclasses and other reasonably advanced code.

My first projects involved generating HTML reports and sending them out via email. This is a simple enough task using a POP3 library and the Jinja2 templating engine and worked well for my needs. Eventually I got around to wanting a web interface so that the reports could be viewed on demand, rather than in an email. After going through a couple Python web frameworks, I found that Flask gave me the flexibility I wanted. Everything was well and good, until I wanted to add dynamic components to my pages.

Enter JavaScript

I avoided JavaScript for a long time. Much of my prior experience was directly manipulating the DOM (Document Object Model) through straight JavaScript. As most will tell you, this isn’t a particularly fun experience, which is why libraries like jQuery were created. These experiences left a bad taste in my mouth and I wasn’t eager to try it again. However, if you want to do client side scripting in the browser JavaScript is really the only choice. (I’m ignoring things like Java applets, Flash, and Silverlight, because they’re horrible.)

During a conversation with one of the web developers at work I was introduced to Angular, a JavaScript web framework. I didn’t think to too much about it at the time, but made a mental note to take look at it at some point.

Coincidentally, it wasn’t more than a day later I was looking for something new to learn on Pluralsight1 and ran across Scott Allen’s AngularJS: Get Started. I was surprised how easy it was to get a web app working with Angular. I immediately started rewritting some of the UI I had been working on with Python/Flask in JavaScript/Angular.

A brief divergence into SPAs

While I don’t want to get too in-depth on Angular, I should explain that Angular is a single page app framework. This means that page changes don’t require the browser to request the entire HTML document from the server again. Typically, if new content is needed only the data is requested from the server via an XHR call2 and the DOM is manipulated to display the new content.

Using a blog post as an example. Assume we’re looking at the home page of a blog, a list of links to articles is displayed. We then click on one of the links:

  • If the site is using server side rendering (Ruby on Rails, Django, Flask, etc) the process happens something like this:

    1. The client (browser) sends a request for the page to the webserver.
    2. The server gets the post metadata and content from a database.
    3. The data is then combined with a template and transformed into HTML.
    4. The server sends the HTML back to the client, which discards the currently rendered page content and renders the new HTML.
  • In a SPA the process is like this:

    1. The client requests the article data from the server’s API via XHR.
    2. The server gets the data from the database and sends it back, formatted as JSON.
    3. The client takes the data and the template it has in memory and uses that to manipulate the current page to show the desired content. (The template may be preloaded or requested via a seperate XHR call.)

While there are a number of benefits (and some tradeoffs) of SPAs, the major advantages are only the necessary data needs to be transferred, rather that the entire page, and the page doesn’t need to completely reload.

Back to the topic at hand

All of that was simply too explain that to write an SPA, you need a server side application to handle API requests. As I was already using the Python-based Flask framework and most web frameworks can be used to send and receive JSON (aka provide an API), it seemed like the logical choice.

So I began writing my API in Flask. It was easy and worked well for the most part. I didn’t have any major complaints.

My minor complaints were:

  1. Figuring out which WSGI server to use for a production deployment can be confusing, especially since I’d been writing in Python3. (I ended up using gunicorn behind a NGINX proxy)
  2. Doing tasks asynchronously is not very straightforward in Python. While I’m certain it’s possible, since I was focusing on writing functionality, I didn’t spend a lot of time looking into it.
  3. Switching between JavaScript and Python took a bit of adjustment. Not really a complaint against either language, but it is the reality of working in a single project with multiple languages.

Taking JavaScript to the server with NodeJS

If you’re even remotely invloved with scripting, you’ve likely heard NodeJS mentioned. It’s one of the hot platforms at the moment. For those that aren’t familar, Node is an implementation of JavaScript which is run server side, like Python or Ruby. It’s built on top of Chrome’s very fast V8 JavaScript engine.

By this time I had become comfortable writing JavaScript for my Angular projects. While not as familar with the language as I was with Python I never had a problem accomplishing what I needed through a little Googling. The switching back and forth between Python and JavaScript was getting a little old and I was curious to learn something new, so I decided to convert my API to Node.

I decided to look for a primer on Pluralsight (surprising, I know) and came across Jonathan Mills RESTful Web Services with Node.js and Expres, perfect! Express is to Node a bit like Flask is to Python, a web framework that doesn’t dictate how your application should work. In fact, the route definitions felt very similar to Flask, except that instead of using decorators to tie routes to logic, callbacks are used. My API wasn’t very complicated as it wasn’t much more than a wrapper around MongoDB queries, so it didn’t take more than an evening to port it to Node/Express.

I was very pleased with the results. I didn’t do any benchmarking, but the API felt faster. Node itself includes a production worthy web server and is built from the ground up to be non-blocking, so I didn’t have to hassle with anything like gunicorn. Some of the API calls required multiple queries to the database (yay for non-relational databases!), this was quite slow in my synchronous Python script. Using the fantastic async library I was able to easily chain query execution together in series, parallel, or a combination, where approriate. As would be expected, this resulted in a massive speed up of those API requests.

The Takeaway

These days, when I have the choice I do nearly all my work in JavaScript (or Go, but that’s another article). Python is certainly an easy language to learn and I don’t mean to disparage it by any means. It’s used extensively in massive organizations like PayPal and runs much of YouTube. And to be fair, there are some constructs I miss from Python, like comprehensions.

I feel that JavaScript is an equally good choice for beginners, and should be the default choice if you plan on doing any frontend web work. The versatility of being able to use the same language in the browser and server side should not be overlooked. There are even opportunities to directly reuse code between the two. Many of the libraries used on the frontend are also available as Node modules.

Speaking of JavaScript libraries, I’m going to give a shout out to Moment.js. It’s by far the best time library I’ve ever worked with and good time libraries are invaluable. My opinion on Python’s datetime… is not positive.

I’ve recently moved my blog to Jekyll, so if I haven’t implemented comments by the time you read this, feel free to hit me up on Twitter, @vCabbage.


Footnotes:

  1. Disclosure: As a Cisco Champion, I received a year subscription to Pluralsight for free. However, I’ve been paying for my own subscription since they aquired Trainsignal and am a huge fan of the service.

  2. XHR: XMLHttpRequest aka AJAX aka JavaScript asking the server for data asynchronously. Despite the name, any type of data can be requested. Nowadays the most common is JSON.