Web applications need servers, right? Wrong! (Sort of.) Using Firebase and a JavaScript library like React, you can make web applications that don’t need a traditional application server. This is pretty neat because it makes it easier and cheaper to experiment with side projects. I just finished one up, and I thought I’d share some of the things I learned. Here’s the finished product.

The app

A while ago I ran into a fun site - Commit Logs From Last Night. I was looking for an excuse to learn some Golang, and digging through lots of Github data seems like a good use case. Also, at the time, Commit Logs From Last Night wasn’t working (it has since been fixed with the efforts of a new contributor), so I set about to reimplement it using as many shiny new things as I could find. I figured out pretty early on that if I had some sort of job that nightly updated Firebase with data, I could just use React.js to build a really simple front end. This avoided the need to pay for a server, or deal with the big startup lag of Heroku’s free tier.

The code

The data

First off I had to figure out how to search through tons of Github data to find swear words. Getting the data using Golang proved to be challenging for me. The GitHub Archive provides public GitHub activity data in gzipped files, but I couldn’t get Golang to un-gzip the response. So after fighting with the language for a while, I simply downloaded the files to disc, then re-opened them, which made un-gzipping much easier. There is one file per hour, so I’m downloading 24 files, saving them, re-opening them, then parsing them. This is terrible, but it’s my first Golang project and I have lots to learn.

Now that I had JSON, parsing it was incredibly easy using Go. First, I made some Structs with field names that matched the JSON keys I cared about. The structs can even be nested – my Event struct has references to the EventActor and EventPayload structs, and the EventPayload struct references the CommitCommit struct.

type Event struct {
    Type       string
    Created_at string
    Actor      EventActor
    Payload    EventPayload
}

type EventActor struct {
    Login      string
    Avatar_url string
}

type EventPayload struct {
    Size    int
    Commits []CommitCommit
}

type CommitCommit struct {
    Message string
    Url     string
}

After defining the structs, I could parse the JSON simply by providing json.Unmarshal my JSON data as a []byte and a pointer to a struct. The function returns an error, and stores the parsed data in the provided struct. Below is my JSON parsing function, where I take a JSON blob as a string input.

func parseEvent(line string) {
    // make a new variable, which is of the type Event, defined above
    var event Event

    //give the parsing function the json data, and a pointer to the variable
    jsonErr := json.Unmarshal([]byte(line), &event)
    if jsonErr != nil {
        // handle error
    }

    //Our 'event' variable is magically filled with data we can use
    if event.Type == "PushEvent" && event.Payload.Size > 0 {
        // look for dirty words
    }
}

Now that I had parsed the JSON, searching for swear words was pretty easy. I just wrote a naive loop that looks through all the words in the commit message and compares them to a list of swear words. Getting the data to Firebase was also easy using this Go package.

Despite all the horrible things I did with Golang, it runs fast. My script can search an entire day’s worth of public GitHub commit messages in one minute on my Macbook, including download time, which is the vast majority of the actual time cost. Here it is on GitHub.

The front end

I made the front end in plain React.js, without Redux or Flux or anything like that. It’s pretty simple, and there’s not a whole lot to say about it, as there are lots of good React tutorials. I used Gulp for the first time, and wrote the components in ES6. I’ll be glad when we all decide on The One True Way to build JavaScript apps.

Getting data from Firebase was of course really easy, and the API provided some nice features. Here is the front end code if you’re interested in checking it out.

The infrastructure

Golang

I used Heroku’s free tier to run my Golang program. Golang is officially supported by Heroku now, and they have a good getting started guide, and another guide, with a lot more detail, that’s focused on getting an existing Golang app working on Heroku. You’ll probably want the second link. One note – Heroku uses Godeps, a tool which I’d never used, but it was very easy to set things up.

In my case all I needed was a worker to run the program once a day. So I added a Procfile with one line:

worker: gitmine

Then I used the Heroku Scheduler to fire that worker every night at midnight. That’s it! Note that I used the compiled binary name (not the script) for Heroku, as I want Heroku to run the binary. Also note that Heroku builds it’s own binaries for you.

Website

I hosted the React-based front end on Amazon’s S3. S3 is usually used to store files, but can also be used for simple static web hosting. It’s not appropriate for production use, but it’s great for small projects, since the cost is minimal. I also used Amazon to register the domain name, so everything was really easy to set up. Here are the S3 web hosting docs.

And, that’s all. Though this isn’t technically a serverless web app, using free-tier Heroku workers, Firebase, and S3 is a great way to get side projects up on the web for essentially no money.

You can check out the result at gitmine.org.