Help us understand the problem. What is going on with this article?

Go lang入門 GinとGORMでWebApp

More than 1 year has passed since last update.

Goを入門することにした

最近よく聞くGo言語。
私は、Ruby,Pythonなど動的言語ばかりでほぼ静的言語の経験はありません。
しかし、静的言語が書けることに憧れがあり何か静的言語やりたいなと思ってました。
Goは、シンプルで扱いやすそうであり、楽しいと聞いたので入門してみました。

Goのインストール

環境はmacOSです。

brew install go

Goの設定

~/.bash_profile
export GOPATH=${HOME}/go
export PATH=$GOPATH/bin:$PATH
go env

でGoの環境変数を参照することができます。

作業ディレクトリを作る

~/goを作り、src pkg binを~/go/以下に作る。

mkdir $GOPATH
cd $GOPATH
mkdir src pkg bin

vim-goをインストール

Vimmer以外はこの手順をステップしてください。
NeoBundleではこのようにインストール

.vimrc
NeoBundle 'fatih/vim-go'

そして

:NeoBundleInstall

をして、再起動後

:GoInstallBinaries

をして、必要なパッケージをインストールします。

vim-goでは、
補完をしたり、
:GoFmtでコード整形されたり(保存時にも自動で整形される)、
:GoRunで実行できたりします。

Hello,World!してみる

~/go/src/hello.goを作成する。

hello.go
package main

import "fmt"

func main() {
        fmt.Printf("Hello,World!\n")
}

go run hello.goまたはvimで:GoRunをすると
Hello,World!を実行する。
一行目のpackage mainでパッケージ宣言をします。
三行目では、fmtパッケージをインポートして、
main()関数のなかで、Hello,World!を表示させる処理を書きます。

基本文法を学ぶ

http://gihyo.jp/dev/feature/01/go_4beginners/0002?page=1
を読んで最低限なところは学びました。

とりあえずGoでWebをやってみたい

今回はginというGo製のWebフレームワークを使ってみます。
ORマッパーはGORMを使用。

Ginフレームワークの特徴

軽量なフレームワーク。
Go製のフレームワークにはRevelなどフルスタックなフレームワークが存在しますが、今回は軽いものをサクッと作りたかったので、ginにしました。
こちらによると、Ginが他のGoのWAFに比べてレスポンスの速度が早いらしいです。

GORMの特徴

かなり高機能で、RubyのActiveRecordに似ている。

Ginのインストール

go get github.com/gin-gonic/gin

ブラウザにHello,World!してみる

~/go/src以下に作業用ディレクトリを作る。

mkdir ~/go/src/gin-first-app

~/go/src/gin-first-app以下のmain.goにコードを書く。

main.go
package main

import "github.com/gin-gonic/gin"

func main() {
        r := gin.Default()
        r.GET("/", func(c *gin.Context) {
                c.String(200, "Hello,World!")
        })
        r.Run()
}

そして、go run main.goして、
http://localhost:8080 に行くと、、、
スクリーンショット 2018-06-11 20.54.37.png
Hello,World!されました。

簡単な名簿WebAppを作ってみた

こんな感じです。
gin_people_app_2.gif
名前と年齢を入力して、登録することができます。

ORMマッパーGORMを使う

gormインストール

go get -u github.com/jinzhu/gorm

go-sqlite3もインストール

go get -u github.com/mattn/go-sqlite3

データベースの情報をHTMLに表示させたいので、作業ディレクトリ以下(gin-first-app)にtemplatesディレクトリを置きましょう。
そしてそれ以下にindex.tmplを作成してください。

main.goを編集

main.go
package main

import (
        "fmt"
        "strconv"
        "github.com/gin-gonic/gin"
        "github.com/jinzhu/gorm"
        _ "github.com/mattn/go-sqlite3"
        _ "net/http"
)

type Person struct {
        gorm.Model
        Name string
        Age  int
}

func db_init() {
        db, err := gorm.Open("sqlite3", "test.sqlite3")
        if err != nil {
                panic("failed to connect database\n")
        }

        db.AutoMigrate(&Person{})
}
func create(name string, age int) {
        db, err := gorm.Open("sqlite3", "test.sqlite3")
        if err != nil {
                panic("failed to connect database\n")
        }
        db.Create(&Person{Name: name, Age: age})
}
func get_all() []Person {
        db, err := gorm.Open("sqlite3", "test.sqlite3")
        if err != nil {
                panic("failed to connect database\n")
        }
        var people []Person
        db.Find(&people)
        return people

}
func main() {
        r := gin.Default()
        r.LoadHTMLGlob("templates/*")
        db_init()
        r.GET("/", func(c *gin.Context) {
                people := get_all()
                c.HTML(200, "index.tmpl", gin.H{
                        "people": people,
                })
        })
        r.POST("/new", func(c *gin.Context) {
                name := c.PostForm("name")
                age, _ := strconv.Atoi(c.PostForm("age"))
                create(name, age)
                c.Redirect(302, "/")
        })
        r.Run()
}

ポイント

  • type Person structでTable構造を宣言
  • db_init()でマイグレーション
  • /newにポストされたname,ageのデータをcreate()関数に渡してレコードを追加する
  • /newは最後/にリダイレクトする

index.tmplを編集

index.tmpl
<html>
<head>
    <title>The first app on Gin WAF </title>
</head>
<body>
    <h1> 一覧</h1>
<form method="post" action="/new">
    <p>名前<input type="text" name="name" size="30" placeholder="入力してください" ></p>
    <p>年齢<input type="number" name="age" ></p>
    <p><input type="submit" value="Send"></p>
</form>
<ul>
    {{ range .people }}
        <li>{{.Name}}さん{{.Age}}才</li>
    {{ end }}
</ul>
</body>
</html>

ポイント

  • rangeで配列を繰り返ししている
  • range ~ end の中ではドットにメンバ名を指定し表示することができる

感想

昨日からGoを始めたので、ここはこんな書き方で大丈夫なのかな、、っていう不安が残ります。
最初は全然なれなくて書くことは面白くなかったけどじわじわ楽しくなってきました。
もっとスラスラ書きたいですね。

参考文献

http://gihyo.jp/dev/feature/01/go_4beginners

https://qiita.com/kent_ocean/items/6dc9b96db70b4a4c3fa5

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away