Building an API with Go (and how it compares to Laravel)

Welcome

There has been a lot of buzz around Go (golang) lately. I don't tend to be an earlier adopter for new languages since a strong community and proven platform are critical when building software intended for production enviroments.

Go has matured quite a bit since it was introduced in 2007, so I decided to take a deeper look this week. My research concluded that it makes a good fit for scalabale (enterprise level) web apps, and API's in specific.

Go supports concurrency and multi-threading on the language level, right out of the box. It also enforces strict syntax and formatting rules - making your code more standardized and less error prone. There are other advantages like built in testing tools and fast compiling speed, but I won't harp on those too much. I don't consider either of those a differentiating factor.

I wanted to give Go a try and build a practical application that we would normally develop here at Kettle. A simple API, hooked up to MySQL seemed like the perfect concept.

Lets do this!


Prerequisites

Since I wanted to test the full life cycle of a Go application I needed to setup a remote enviroment on Heroku. I won't go into too much detail on how to set these up, but below are some resources that I found extremely helpful:

The Code

I found a nifty framework called Martini that was designed to make the code more modular and quicker to write. I came up with the following code for my super simple sudo-API:

package main

import (  
    "github.com/go-martini/martini"
    _ "github.com/go-sql-driver/mysql"
    "database/sql"
    "fmt"
)

func main() {

    // Connect to database
    db, err := sql.Open("mysql",
        "user:pass@tcp(localhost:3306)/tableName")


    // Fire up martini & define route
    m := martini.Classic()
    m.Get("/api/:id", func(params martini.Params) string {   

          // Define variables
          var str string
          var userId =  params["id"]

          // Run MySQL query against param
          err = db.QueryRow(
              "select name from users where id = ?", userId).Scan(&str)


          // Check for errors and log if they exist     
          if err != nil && err != sql.ErrNoRows {
              fmt.Println(err)
          } 

          return str 

    })

  m.Run()
  defer db.Close()

}

Just How Fast Is It?

Now that I had a functioning piece of Go code I wanted to see just how fast the language was. After hearing all the praises of the language I needed to see first hand how good/bad it was.

To test the app I used a service called Loader.io (awesome tool by the way). I had Loader query the service with 4,000 clients (making 2 requests each) over the course of 60 seconds and these are the results I saw:

The results are astounding. I was running a free Heroku instance and free database from ClearDB. Regardless of those limitations, the app managed an average response of 35ms with zero errors. I found this impressive for three reasons:

  • The response times were quick and consistent
  • The error rate was zero which is important
  • The app handled many requests per second on limited server resources without issue (think: cheap infastructure costs at scale)

Compared to Laravel 5

My intention here was to learn Go and see if it was really as good as people said. After seeing the results, I'm pretty convinced it is good. However, I was curious to see how it would stack up against Laravel 5, an awesome PHP framework we use quite often here at Kettle. I knew this wasn't a fair comparision, but I did it anyway. Here is the code we used in Laravel:

routes.php

<?php

Route::get('/', 'WelcomeController@index');  
Route::get('/api/{user}', 'ApiController@user');  

ApiController.php

<?php 

namespace App\Http\Controllers;  
use DB;

class ApiController extends Controller {

    public function user($user) {
        $response = DB::table('users')->where('id', $user)->first();

        return $response->name;
    }

}

I ran the same test again - 4,000 clients over the course of 60 seconds, each making 2 requests. These are the results observed:

Conclusion

As expected, Laravel performed much slower than Go. I believe Go is a great choice for something like an enterprise API. It's quick and predicable. This makes it easy to scale.

Laravel has it's place too - it allows us to build robust web apps, quickly. That makes it a great fit for projects that require quick turn around and agile development.

We hope you enjoyed this article. Please feel free to leave comments below.