Paiza Engineering Blog

Engineering blog of browser-based web development environment PaizaCloud Cloud IDE ( https://paiza.cloud/ ), online compiler and editor Paiza.IO( https://paiza.IO/ )

Go/Revel Tutorial: How to create Go(golang) web framework Revel app in browser with PaizaCloud Cloud IDE

f:id:paiza:20180323134353p:plain
(Japanese article is here)

f:id:paiza:20151217152725j:plainHello, I'm Tsuneo!(@)

Go language(golang) have features like: - Standard library has many features including networking. - Easy to write concurrent programs. - Easy to manage executable files as it is only one file.

With these features, Go language is also getting popular for web development.

We can see the popularity from Google Trends below.

f:id:paiza:20180323105259p:plain From google trends

Although we can build web applications only by using Go's rich standard library, web application frameworks make it easier to develop the full-fledged web applications.

There are many Go web application frameworks like Revel, Echo, Gin, Iris, Revel is one of the most popular full-stack web application framework.

Go framework Revel has features for web development like routing, MVC, generator. By building the application following Revel rules, you can naturally create readable and extensible Web Applications. You can also use OR mapper library like Gorm with the Revel.

But, to develop Revel application in practice, you need to install and setup Go, Revel, Gorm, or databases. These installation and setting up can be frustrating. Just following the installation instruction does not work or cause errors because of OS, versions, other software dependencies, etc.

Also, if you publish the service, feedback from your friends or others will motivate you. But, this requires "deployment" of the service. The "deployment" also frustrates us...

So, here comes PaizaCloud Cloud IDE, a browser-based online web and application development environment.

As PaizaCloud have Go/Revel application development environment, you can just start coding for the Go/Revel application program in your browser.

And, as you can develop in the cloud, you can just run the Go/Revel application on the same machine without setting up another server and deploying to it.

Here, we develop a Task List application using Go and Revel on the PaizaCloud Cloud IDE.

Following the instruction below, you'll create and run the Google Home application just in 10 minutes.

Getting started with PaizaCloud Cloud IDE

So, here is the website of PaizaCloud Cloud IDE.

https://paiza.cloud/

Just sign up with email and click a link in the confirmation email. You can also sign up with GitHub or Google.

Create new server

Let's create a new server for the development workspace.

f:id:paiza:20171214154558p:plain

Click "new server" to open a dialog to set up the server.

Here, you can choose "PHP", "phpMyAdmin", and "MySQL", and click "New Server" button.

f:id:paiza:20171214154330p:plain

Just in 3 seconds, you'll get a browser-based development environment for Go and Revel.

You'll see editor or browser windows in the page, but we can close those for now.

Setup environment

Let's set up the environment. As PaizaCloud already have Go language or MySQL installed, you can just run "go get" command to install additional packages.

On PaizaCloud Cloud IDE, you can use PaizaCloud's "Terminal" application to run the commands in your browser.

Let's click the "Terminal" button at the left side of the page.

f:id:paiza:20171214154805p:plain

Now, the "Terminal" application launch. So, let's type "go get [package name]" command in the Terminal.

The '[package name]' is the name of the package to install. Here, we install packages for Revel and Gorm.

So, lets type:

$ go get github.com/revel/revel
$ go get github.com/revel/cmd/revel
$ go get github.com/jinzhu/gorm
$ go get github.com/go-sql-driver/mysql

f:id:paiza:20180323105536p:plain

Now, we have installed the packages to "~/go/bin" .

Create an application

Then, let's create your Go/Revel application.

You can use "revel new" command to create Go/Revel application.

On PaizaCloud Cloud IDE, you can use PaizaCloud's "Terminal" application to run the commands in your browser.

Let's click the "Terminal" button at the left side of the page.

f:id:paiza:20171214154805p:plain

Now, the "Terminal" application launch. So, let's type "revel new [application name]" command in the Terminal.

The '[application name]' is the name of the application you are creating. You can choose whatever you want, like "music-app" or "game-app".

Here, I'll choose the application name "myapp", where I can manage the Task List.

So, lets type:

$ revel new myapp

f:id:paiza:20180323111349p:plain

In the file manager view at the left side of the page, you'll see the "go/src/myapp" directory. Click the folder to open it to see inside the directory.

f:id:paiza:20180323110203p:plain

You'll see a bunch of files for the Go/Revel application.

Start Revel server

Now, you can already run the application. Let's start the application.

Change the directory by typing "cd ~/go" command, and type "revel run myapp" command to start the server!

$ cd ~/go
$ revel run myapp

f:id:paiza:20180323111505p:plain

You'll get a new button with text "9000" on the left side of the page.

f:id:paiza:20180323111533p:plain

Revel server runs on port 9000. PaizaCloud Cloud IDE detects the port number(9000), and automatically adds the button to open a browser for the port.

Click the button, and you'll get Browser application(a Browser application in the PaizaCloud). Now, you'll see web page about the Revel, that is your application!

f:id:paiza:20180323111629p:plain

(Although Revel runs as HTTP server, PaizaCloud can convert from HTTP to HTTPS.)

Editing file

What you see on the application page is an HTML file "~/go/src/myapp/app/views/App/Index.html". Let's try to change the title by editing the file.

On file manager view, double-click the file "~/go/src/myapp/app/views/App/Index.html" for editing.

f:id:paiza:20180323111814p:plain

Edit the title part by replacing 'It works!' like below:

go/src/myapp/app/views/App/Index.html:

      <h1>Hello Go and Revel!</h1>

f:id:paiza:20180326143312p:plain

After the editing, click "Save" button or type "Command-S", or "Ctrl-S" to save the file.

If the server is not running, start the server by typing:

$ revel run myapp

The, click the browser icon with text "9000" on the left-side of the page. If you already have the running browser, click reload button.

f:id:paiza:20180326143503p:plain

You got the message you just wrote on the page!

Create database

You'll already have a MySQL server running because you checked it on the server setting. But if not, you can always manually start like:

$ sudo systemctl enable mysql
$ sudo systemctl start mysql

On PaizaCloud Cloud IDE, you can install packages on root privilege.

Next, create a database for the application. Here, we create a database "mydb" using "mysql" command. Type the command below to create the "mydb" database.

$ mysql -u root
create database mydb;

f:id:paiza:20180216010049p:plain

You created the database.

Then, set the application to use the database. Database configuration file is "conf/app.conf" under the project directory.

Setting for development mode can be written in "[dev]" section. Database settings can be written as "db.info = [DB user]:[DB password]@/[DB name]?[DB options]"

Here, we set DB user as "root", empty password, DB name as "mydb", and some options. So we write the "db.info" setting like below under "[dev]" section.

go/src/myapp/conf/app.conf:

[dev]
db.info = root:@/mydb?charset=utf8&parseTime=True

Then, we create a file "app/controllers/gorm.go" to write code to use the database.

On file manager view, right-click "go/src/myapp/app/controllers" directory to open the context menu, and choose "New File" menu.

f:id:paiza:20180326143634p:plain

Input filename as "gorm.go", and click "Create" button to create the file.

f:id:paiza:20180326143715p:plain

An editor opens, let's write the code like below:

go/src/myapp/app/controllers/gorm.go:

package controllers

import (
    _ "github.com/go-sql-driver/mysql"
    "github.com/jinzhu/gorm"
    "github.com/revel/revel"
    "myapp/app/models"
    "log"
    )

var DB *gorm.DB

func InitDB() {
    dbInfo, _ := revel.Config.String("db.info")
    db, err := gorm.Open("mysql", dbInfo)
    if err != nil {
        log.Panicf("Failed gorm.Open: %v\n", err)
    }

    db.DB()
    db.AutoMigrate(&models.Post{})
    DB = db
}

After the editing, click "Save" button or type "Command-S", or "Ctrl-S" to save the file.

Let's see the code.

On "InitDB()" function, it reads the DB settings from "db.info" line of the configuration file, and open the database using Gorm library. Then, "db.AutoMigrate()" creates a table from Post model we'll create later. It assigns the database handle to "DB" variable so that other files can access the database as "controllers.DB".

Next, edit "app/init.go" to call the InitDB() function.

go/src/myapp/app/init.go:

package app

import (
  "github.com/revel/revel"
  "myapp/app/controllers"
)

...

func init() {
  ...
  revel.OnAppStart(controllers.InitDB)
}

...

There are two lines to add. The first change is to add "myapp/app/controllers" to "imports", and the second change is to add "revel.OnAppStart(controllers.InitDB)" at the end of init() function to call "InitDB()" on "germ.go" we just created.

Create table, model, etc.

Next, let's create a database table.

With Gorm library, we can manipulate the database using model information written in Go struct.

Here, we manipulate the "post" table stored Todo list information, using "Post" model.

We create the "Post" model on "app/models/post.go" file.

Right-click the "go/src/myapp/app" directory to open the context menu, and choose "New directory" menu, and create "models" directory. Right-click the "go/src/myapp/app/models" directory to open the context menu, and choose "New File" menu, and create "post.go" file. Then, edit the created "app/models/post.go" file like below.

go/src/myapp/app/models/post.go:

package models

type Post struct {
    Id  uint64 `gorm:"primary_key" json:"id"`
    Body string `sql:"size:255" json:"body"`
}

Let's see the code. "Post" struct have an integer type field "Id", and a string type field "Body". These represent "id" column and "body" column of the "posts" database table.

Exit and restart the server.

$ cd ~/go
$ revel run myapp

On the application startup, database migration is executed to create "posts" table. We can see the table data using "phpMyAdmin".

On browser on PaizaCloud, type "http://localhost/phpmyadmin/" on the URL field.

f:id:paiza:20180323132256p:plain

We can see the "posts" table. Here, we can add, edit or delete the database records.

Routing settings

The Todo List application has 3 actions: listing todos, adding a todo, or deleting a todo. We set 3 routing for those like below.

Method Path Action
GET /posts List tasks
POST /posts Add a task
DELETE /posts/{id} Delete a task

We set those routing on "routes/web.php" file. At first, remove all the default routings on the file. For about top page "/", set to redirect to "/tasks".

Edit "conf/routes" file like below.

go/src/myapp/conf/routes:

GET     /                                       Post.RedirectToPosts
GET     /posts                                  Post.Index
POST    /posts                                  Post.Create
POST    /posts/:id/delete                       Post.Delete

Let's see the code. "GET /" request calls RedirectToPosts method of Post controller. "GET /posts", "POST /posts", "POST /posts/:id/delete" requests calls "Index", "Create", "Delete" methods of Post controller. The controller methods can refer ":id" part as a parameter.

Controller settings

Create a Post controller referred by the router as "app/controllers/post.go".

Right-click the "app/controllers" directory to open the context menu, and choose "New file" to create "post.go" file.

Define Index(), Create(), Delete() methods for listing, adding, deleting todos.

go/src/myapp/app/controllers/post.go:

package controllers

import (
    "github.com/revel/revel"
    "myapp/app/models"
    "errors"
)

type Post struct {
    *revel.Controller
}

func (c Post) Index() revel.Result {
    posts := []models.Post{}

    result := DB.Order("id desc").Find(&posts);
    err := result.Error
    if err != nil {
        return c.RenderError(errors.New("Record Not Found"))
    }
    return c.Render(posts)
}
func (c Post) Create() revel.Result {
    post := models.Post{
        Body: c.Params.Form.Get("body"),
    }
    ret := DB.Create(&post)
    if ret.Error != nil {
        return c.RenderError(errors.New("Record Create failure." + ret.Error.Error()))
    }
    return c.Redirect("/posts")    
}
func (c Post) Delete() revel.Result {
    id := c.Params.Route.Get("id")
    posts := []models.Post{}
    ret := DB.Delete(&posts, id)
    if ret.Error != nil {
        return c.RenderError(errors.New("Record Delete failure." + ret.Error.Error()))
    }
    return c.Redirect("/posts")    
}

func (c Post) RedirectToPosts() revel.Result {
    return c.Redirect("/posts")    
}

Let's see the code.

Add "myapp/app/models" to "import" so that we can access the Post model. Create Post controller at "type Post struct".

"func (c Post) Index() revel.Result" is a Index() method of the Post controller to return the Todo list. "posts := []models.Post{}" create "posts", an array of Post model. 'DB.Order("id desc").Find(&posts)' retrieve all the "posts" table records, and store them to the "posts" array. Then, if there is no error, call Render() method to create the HTML file. The HTML file is created from the HTML template we will create later on. By setting "posts" to Render() argument, the template file can refer the "posts" table.

"func (c Post) Create() revel.Result" is Create() method of the Post controller to create a Todo. "models.Post{...}" creates a model, retrieve the "body" parameter of the submitted form using "c.Params.Form.Get()", and set it to "Body" field of the model. "DB.Create(&post)" create a database record from the model. Then, redirect to the Todo list page using 'c.Redirect("/posts")'.

"func (c Post) Delete() revel.Result" is a Delete() method of the Post controller to delete a todo. 'c.Params.Route.Get("id")' get the ":id" part of the URL: "/posts/:id/delete". "DB.Delete(&posts, id)" deletes an record of the "id". Then, 'c.Redirect("/posts")' redirects to the Todo list page.

"func (c Post) RedirectToPosts() revel.Result" is to redirect from the top page to Todo list page.

Create HTML template

Next, let's create HTML a template. An HTML template is an HTML file with embedded code.

Create an HTML template file to list, add, and delete Todo as "app/views/Post/index.html".

Right-click "go/myapp/app/views" directory to open the context menu, choose "New Directory" menu, and create "Post" directory. Right-click "go/myapp/app/views/Post" directory to open the context menu, choose "New File" menu, and create "index.html" file.

Edit the created "app/views/Post/index.html" file as below.

go/myapp/app/views/Post/index.html:

{{set . "title" "Todo list"}}
{{template "header.html" .}}

<header class="jumbotron" style="background-color:#A9F16C">
  <div class="container">
    <div class="row">
      <h1>Todo list</h1>
      <p></p>
    </div>
  </div>
</header>

<div class="container">
  <div class="row">
    <div class="span6">
      {{template "flash.html" .}}
    </div>
  </div>
</div>

<div class="container">
    <form action="/posts" method="post">
        <div class="form-group">
            <div class="row">
                <label for="todo" class="col-xs-2">Todo</label>
                <input type="text" name="body" class="col-xs-8">
                <div class="col-xs-2">
                    <button type="submit" class="btn btn-success">
                        <i class="fa fa-plus"></i> Add Todo
                    </button>
                </div>            
            </div>
        </div>
    </form>

    <h2>Current Todos</h2>
    <table class="table table-striped todo-table">
        <thead>
            <th>Todos</th><th>&nbsp;</th>
        </thead>

        <tbody>
            {{ range .posts }}
                <tr>
                    <td>
                        <div>{{ .Body }}</div>
                    </td>
                    <td>
                        <form action="/posts/{{.Id}}/delete" method="post">
                            <button class="btn btn-danger">Delete</button>
                        </form>
                    </td>
                </tr>
            {{ end }}
        </tbody>
    </table>
    
</div>


{{template "footer.html" .}}

Let's see the template file. On the HTML template, a part between "{{" and "}}" is to describe actions which creates HTML.

'{{set . "title" "Todo list"}}' sets "title" variable as "Todo list".

'{{template "header.html" .}}' creates HTML file from a template file "header.html". By calling other HTML templates like this, we can share common parts for multiple template files as the one template file. Here, "header.html" have common HTML header part.

'<form action="/posts" method="post">' is to create a Todo form.

'<input type="text" name="body" class="col-xs-8">' shows a text input form to input a Todo. Set form name to "body" so that "body" parameter of the submitted request has the inputted Todo.

The part between '{{ range .posts }}' and '{{ end }}' is read through posts array, and create HTML from HTML template inside repeatedly for each post.

'{{ .Body }}' shows the "Body" field of each post. '{{.ID}}' shows the Id field of each post.

And, '{{template "footer.html" .}}' shows the HTMP footer from the "footer.html" template.

Run the application

Now, we wrote all the code. Let's see.

Click the browser icon(9000) to open the browser in PaizaCloud.

We see the "Task List" page with the empty task.

Let's add or delete the tasks.

f:id:paiza:20180326144011p:plain

It works! We successfully created the Task List application with Go/Revel!

Note that on PaizaCloud free plan, the server will be suspended. To run the bot continuously, please upgrade to the BASIC plan.

Summary

With PaizaCloud Cloud IDE, we created a Go/Revel application just in your browser, without installing or setting up any development environments. We can even publish the application just on the PaizaCloud. Now, let's create your own Go/Revel application!


With「PaizaCloud Cloud IDE」, you can flexibly and easily develop your web application or server application, and publish it, just in your browser. https://paiza.cloud