As the Ruby on Rails community becomes increasingly mature, additional time is spent optimizing different aspects of the program rather than creating a completely new web application. This means performance and memory consumption start to play a significant role in its day-to-day development. So now we have much more instantaneous communication, lots of API calls and open connections needs to be processed. This evolution is apparent from the way Rails 5 was developed. ActionCable and API mode for Rails are selling features of Rails 5 due to the program’s advances over time. But what happens if you still encounter problems with performance and concurrency? Luckily, Golang has the capacity to address some of these issues in certain circumstances.

To be clear, however, this article isn’t designed as a complete guide to explain Golang’s most complex facets. Instead, it presents similarities between the two major frameworks of Golang and Ruby. Therefore, the purpose is to compare Ruby on Rails versus Beego. In the process, the objective is to discover familiar ways to perform functions in Go if you already have some experience using Ruby.

Getting Up and Running

The first step is to install Beego and Rails.

Installation

Fortunately, the installation itself is fairly simple. In fact, the only difference is that for a more robust experience, you have to install the Bee command. That’s the Rails alias for Beego, which allows you to run several useful commands in order to get up and running as fast as possible. Here are your typical workflows in Rails and the equivalent in Go

Ruby
$ gem install rails

Now let’s install the required packages for Beego:

Go
  $ go get github.com/astaxie/beego
  $ go get github.com/beego/bee

Make sure that after the installation, Bee will be somewhere in the $PATH.

To be confident everything is correct, run “bee -h” and if “bee” was installed properly, you will see the following help information:

$ bee -h

Bee is a fast and flexible tool for managing your Beego web application.

  USAGE
    bee command [arguments]

  AVAILABLE COMMANDS

    version     Prints the current Bee version

Now we can start our journey into the Beego app development. To begin, it’s best to try to find equivalents for everyday tools that are already used in Rails.

Generators

When Rails became a popular program, one of the most innovative aspects was its generators. This tool impressed newcomers with its simplicity and speed. Today, it might be difficult to imagine any kind of mature framework that does not include a code generator tool in a toolchain. Below, you will see the most common cases solved for both Ruby and Go.

Ruby
$ rails new ror
Go
$ bee new beeapp

You can generate controllers, models, migrations, even scaffolds. So from this point of view, you have all of the familiar tools out of the box.

Start the Engine

Both frameworks (Rails and Beego) come with numerous helpful tools that are designed to assist you. Now let’s try them out.

Ruby
  $ rails s

  => Booting Puma
  => Rails 5.1.2 application starting in development on http://localhost:3000
  => Run `rails server -h` for more startup options
  Puma starting in single mode...
  * Version 3.9.1 (ruby 2.3.4-p301), codename: Private Caller
  * Min threads: 5, max threads: 5
  * Environment: development
  * Listening on tcp://0.0.0.0:3000
  Use Ctrl-C to stop

 

Go
  $ bee run

  ______
  | ___ \
  | |_/ /  ___   ___
  | ___ \ / _ \ / _ \
  | |_/ /|  __/|  __/
  \____/  \___| \___| v1.8.4
  2017/07/15 22:58:35 INFO     ▶ 0001 Using 'beeapp' as 'appname'
  2017/07/15 22:58:35 INFO     ▶ 0002 Initializing watcher...
  beeapp/controllers
  beeapp/routers
  beeapp
  2017/07/15 22:58:37 SUCCESS  ▶ 0003 Built Successfully!
  2017/07/15 22:58:37 INFO     ▶ 0004 Restarting 'beeapp'...
  2017/07/15 22:58:37 SUCCESS  ▶ 0005 './beeapp' is running...
  2017/07/15 22:58:37 [I] [asm_amd64.s:2197] http server Running on http://:8080

 

Dependency Management

As your application grows, you will start to use more and more third party packages. So it’s crucial to have a reliable dependency management tool in place. Let’s take a look at how we can use this approach.

 

  $ bundle install
  $ glide init

With the above method in place, we can now examine a particular part of our app. First of all, we need to generate a basic model and see the difference between the ActiveRecord model and the Gorm.

Models

At the heart of any app, you’ll find data layers. So from this point, it’s best to start our feature comparison from Models. But first, let’s talk a bit about the Model from the MVC pattern. This is a foundation of your project and the most important part of the app. By default, Beego is fully packed with ORM (Object Relation Mapping) and migrations support. Still, we should take advantage of the nature of Go projects and replace the default orm with Gorm.

Ruby
  $ rails g model post titel:string body:text
      invoke  active_record
      create    db/migrate/20170717150150_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/models/post_test.rb
      create      test/fixtures/posts.yml
Go
  $ bee generate model post -fields="title:string,body:text"
  ______
  | ___ \
  | |_/ /  ___   ___
  | ___ \ / _ \ / _ \
  | |_/ /|  __/|  __/
  \____/  \___| \___| v1.8.4
  2017/07/17 18:07:22 INFO     ▶ 0001 Using 'Post' as model name
  2017/07/17 18:07:22 INFO     ▶ 0002 Using 'models' as package name
    create   ~/.go/src/beeapp/models/post.go
  2017/07/17 18:07:22 SUCCESS  ▶ 0003 Model successfully generated!

By default, you can generate models right from the CLI (Command Line Interface) with the Bee app. But it must use default ORM. So if we want to experience advantages from the Gorm, we need to perform this setup manually.

  models
  ├── connection.go
  └── post.go
  models/connection.go
  package models

  import (
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/sqlite"
  )

  var DB *gorm.DB

  func GetNewConnection() *gorm.DB {
    if DB != nil {
      return DB
    }

    db, err := gorm.Open("sqlite3", "test.db")
    if err != nil {
      panic("failed to connect database")
    }
    // defer db.Close()

    DB = db
    return DB
  }
  models/post.go
  package models

  import (
    "github.com/jinzhu/gorm"
  )

  type Post struct {
    gorm.Model
    Title string
    Body  string
  }
  main.go
  package main

  import (
    "beeapp/models"
    _ "beeapp/routers"

    "github.com/astaxie/beego"
  )

  func main() {
    beego.Run()
    models.GetNewConnection()
  }

Controller

At this time, we are ready to work with data and able to perform basic CRUD operations. So it makes sense to add some controllers and actions. We can generate a controller in a same manner as we do in Rails.

Ruby
  $ rails g controller Posts index
      create  app/controllers/posts_controller.rb
       route  get 'posts/index'
      invoke  erb
      create    app/views/posts
      create    app/views/posts/index.html.erb
      invoke  test_unit
      create    test/controllers/posts_controller_test.rb
      invoke  helper
      create    app/helpers/posts_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/posts.coffee
      invoke    scss
      create      app/assets/stylesheets/posts.scss
Go
  $ bee generate controller Post
  ______
  | ___ \
  | |_/ /  ___   ___
  | ___ \ / _ \ / _ \
  | |_/ /|  __/|  __/
  \____/  \___| \___| v1.8.4
  2017/07/17 18:56:55 INFO     ▶ 0001 Using 'Post' as controller name
  2017/07/17 18:56:55 INFO     ▶ 0002 Using 'controllers' as package name
  2017/07/17 18:56:55 INFO     ▶ 0003 Using matching model 'Post'
    create   ~/.go/src/beeapp/controllers/post.go
  2017/07/17 18:56:55 SUCCESS  ▶ 0004 Controller successfully generated!

As you can already see, there are many parallels between Beego and Rails. Both frameworks aim to be “full featured” and incorporate all of the aspects that you need in your day-to-day development. In addition, the shape of these frameworks are the same and they solve similar problems.

Despite that similarity in basic concepts and the scaffolding process, there is a significant difference between these frameworks. They are implemented in completely different languages and there are numerous amounts of corner cases. We can now take a look and apply logic into this process.

One of the most eye catching differences is that we work with data in using Go. On the surface, Rails might look different. However, it operates in a similar way. Therefore, you can set up Rails to look something like this:

  def index
    @users = User.all
  end

  def show
    @user = User.find(params[:id])
  End

 

Compared to Beego, you should perform the following steps:

 

  // GetAll ...
  // @Title Get All
  // @Description get all Posts
  // @Success 200 {object} models.Post
  // @Failure 403
  // @router / [get]
  func (c *PostController) GetAll() {
    posts := []models.Post{}

    if err := models.GetNewConnection().Find(&posts).Error; err != nil {
      c.Data["json"] = err.Error()
    } else {
      c.Data["json"] = posts
    }
    c.ServeJSON()
  }

  // GetOne ...
  // @Title Get One
  // @Description get Post by id
  // @Param id    path  string  true    "The key for staticblock"
  // @Success 200 {object} models.Post
  // @Failure 403 :id is empty
  // @router /:id [get]
  func (c *PostController) GetOne() {
    idStr := c.Ctx.Input.Param(":id")
    id, _ := strconv.ParseInt(idStr, 0, 64)
    post := models.Post{}

    if err := models.GetNewConnection().First(&post, id).Error; err != nil {
      c.Data["json"] = err.Error()
    } else {
      c.Data["json"] = post
    }
    c.ServeJSON()
  }

From this example, you can already observe that in Go you have to be much more explicit about your commands. In short, you must handle “Record Not Found” by yourself and take care of this issue right within the action. This means you need to cast your params manually without later relying on type casting.

Conclusion and Cheat Sheet

Rails was the first of its kind and paved the way for other sophisticated frameworks. In fact, Go is widely considered to be a framework with many Rails characteristics. It provides a full range of tools to work with in your Model, View and Controller layers, which are similar to Rails. Beego has also created extensive routing in streamlined form as well as many other crucial features. It’s worth noting that both Beego and Rails are great tools with minimal overhead required for the mental model switch.

If you hit the performance wall and don’t want to reinvent the wheel, you may consider replacing some parts of your Rails app with Beego to save significant time and effort. Having such advanced products in your toolchain can be very helpful for a wide assortment of projects. Overall, if you have a Rails background and you want to leverage certain advantages from Golang, try Beego. It might be a great start for your Golang journey.

In addition, here is a helpful cheat sheet that you can use for comparison as you progress forward.

Rails Beego
rails new [appname] bee new [appname]
rails s bee run
bundle install glide install
rails g model post titel:string body:text bee generate model post -fields=”title:string,body:text”
rails g controller Posts bee generate controller Post

 

Links

  • http://guides.rubyonrails.org/
  • https://beego.me/

Previous

Next