Media Do Tech Do Blog

株式会社メディアドゥのエンジニアによるブログです。

Goハンズオン#3 開催レポート

f:id:hrk02:20190305144942p:plain
受付をするGopherくん*1

こんにちは!株式会社メディアドゥの奥野です。

今回は弊社で行なっている取り組みのひとつ、Goハンズオンの開催レポートです。 ご好評いただき、この度第3回を迎えることができました!
お菓子を食べながら聞くもよし、お酒を飲みながら聞くもよしのカジュアルなイベントとなっております!

2/18(月)のGoハンズオンでは、Goの基本的な部分に加え、Go modulesについても触れています。

こんな人におすすめ

  • Go言語初心者の方
  • Go modulesについて知らない方
  • Go言語で何か課題を解いてみたい方
  • Goハンズオン勉強会が気になっている方

今回の課題

今回の課題は「Webアプリを作る」です。
制限時間は50分で、 Go modules の使用を想定しています。

課題詳細や、解き方のヒントについては、こちらをご確認ください。

Webフレームワーク「Echo」を使ってみる

今回の課題ではEchoを使用します。
課題3を例に、Echoの使い方を見てみましょう。

課題3: 「http://localhost:8080/hello」にアクセスした際、「Hello world」とレスポンスを返却するプログラムを作成する

サーバの起動

まずmain.goを作成し、Echoを利用してサーバを起動します。
mainメソッドの中で、Echoインスタンスの生成を行い、EchoのStartメソッドを実行することでサーバが起動されます。

package main

import (
    "github.com/labstack/echo"
)

func main() {
    e := echo.New()
    e.Logger.Fatal(e.Start(":8080"))
}

コマンドラインからgo run main.goを実行し、サーバの起動に成功することを確認しましょう。

$ go run main.go

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.0.0
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:8080

HTMLテンプレートを作成する

表示するHTMLテンプレートhello.html.tplを作成します。
Echoでは、{{define "hoge"}}{{end}}を使用します。

{{define "hello"}}
<!DOCTYPE html>
<html>
  <body>
    <h1>{{.Title}} </h1>
    <p>{{.Text}}</p>
  </body>
</html>
{{end}}

Echoにテンプレートエンジンを組み込む

EchoでHTMLテンプレートを使用するため、main.go内で構造体の定義を行います。

type Template struct {
    templates *template.Template
}

続いて、レンダリング処理を行うRenderメソッドを実装します。

func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
    return t.templates.ExecuteTemplate(w, name, data)
}

サーバの起動を実装した際に作成したEchoインスタンスに対して、テンプレートとレンダリングの定義を行います。

t := &Template{
    templates: template.Must(template.ParseGlob("./*.tpl")),
}
e.Renderer = t

HTMLテンプレートを表示するハンドラを登録

/helloにGET通信でアクセスされた際、「Hello world」を表示するHelloメソッドを呼び出します。

e.GET("/hello", Hello)

テキストを返却するメソッドの実装

main.goに、Helloメソッドとテキストの構造体を定義します。

type Message struct {
    Title string
    Text string
}

func Hello(c echo.Context) error {
    m := &Message{
        Title: "Hello world",
        Text:  "hogehoge",
    }
    return c.Render(http.StatusOK, "hello", m)
}

課題3のプログラム完成例

最終的に完成したプログラムがこちらです。
go run main.goを実行し、http://localhost:8080/helloにアクセスしてみましょう。

package main

import (
    "html/template"
    "io"
    "net/http"
    "github.com/labstack/echo"
)

type Template struct {
    templates *template.Template
}

type Message struct {
    Title string
    Text string
}

func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
    return t.templates.ExecuteTemplate(w, name, data)
}

func Hello(c echo.Context) error {
    m := &Message{
        Title: "Hello world",
        Text:  "hogehoge",
    }
    return c.Render(http.StatusOK, "hello", m)
}


func main() {
    e := echo.New()
    e.GET("/hello", Hello)

    t := &Template{
        templates: template.Must(template.ParseGlob("./*.tpl")),
    }
    e.Renderer = t
 
    e.Logger.Fatal(e.Start(":8080"))
}
{{define "hello"}}
<!DOCTYPE html>
<html>
  <body>
    <h1>{{.Title}} </h1>
    <p>{{.Text}}</p>
  </body>
</html>
{{end}}

Go modulesとは?

Go言語では、環境変数 $GOPATH に保存したパスを開発時の作業用ディレクトリとして扱います。
Go言語で書いたコードやライブラリは $GOPATH/src に配置しますが、 そうするとプロジェクトごとにライブラリのバージョンを変えることができません。
そこで、Go言語ではプロジェクト固有のライブラリを $GOPATH/src/{プロジェクト名}/vendor の下に配置しても良いことになっています。(Goコマンドでは $GOPATH/src/{プロジェクト名}/vendor 配下が優先されます。)

しかし2019年2月にリリースされたGo1.12からは、この$GOPATH/srcvendor が廃止され、新たに Go modules が採用されることになりました。
Go modules は 、Goのバージョン管理構想として知られるvgo ライブラリが元となっています。 使い方は、ぜひ公式のスタートアップをご確認ください。

質疑応答

Goハンズオンでは、SlackTwitterを用いて質問を受け付けています。
実際にあった質問と回答を見てみましょう。

── JavaScriptではjasmine・karma・istanbulのように複数組み合わせてテストしているものを、Go言語ではtestingパッケージ1つで出来るということでしょうか。

できると言って良いかと考えます。
testingパッケージはGo言語のテスト用公式ライブラリで、JavaScriptでのjasmineの立ち位置と同じと言っても良いでしょう。
テスト実行環境やカバレッジ取得についてはgoコマンド内に備わっていますので、karmaやistanbulと同じ役割を果たしていると言えます。

── Go modulesなら$GOPATH配下でなくても、どこでも良いのでしょうか。

goプロジェクト自体を$GOPATHの外に置けるようになります。
go getgo installの格納先などは$GOPATHが使われる点は今までと同じです。

── golangをvimで書く場合はどのようなプラグインがあるのでしょうか。

vim-goというプラグインがおすすめです。
vim-go日本語チュートリアルもあるようです。

── Go言語にWebフレームワークが不要となるのはまだ先となりそうなのでしょうか。メジャーとなれるようなフレームワークがないことや、標準のnet/httpパッケージで事足りることが理由としてあげられるかと思いますが...

Go言語自身に「必要なものは標準で備えるべき」という風潮がありそうです。
しかし、マイクロサービスでの連携を前提としたものや、業務に特化したハンドリングや調整が必要となると、フレームワークが提供する開発のしやすさや処理モデルが必要となってくるかもしれません。

勉強会の風景

みなさんじっくり話を聞いて、もくもくと勉強を進めています!

f:id:hrk02:20190308103554p:plain

f:id:hrk02:20190308110737p:plain

わからない部分があっても、スタッフに質問することができます。

f:id:hrk02:20190308110817p:plain

今回のGoハンズオンは動画もアップロードされておりますので、こちらも併せてご覧ください!

crash.academy

Goハンズオン終了後には懇親会を開催しました。
今回のご飯は....??

f:id:hrk02:20190308110643p:plain
みんながだいすきpizza!

f:id:hrk02:20190308110853p:plain

様々な業界のエンジニアが集まり、楽しい時間となりました。

おわりに

今回のGoハンズオンも約50名が参加してくださいました。
Twitterには 「第3回から初参加なので、今までのおさらいしてくれるのありがたい」「ビール飲みながらハンズオン受けるの初かも」「3回目にしてついに初めて全部課題解けた」「課題の時間長めにとってもらった&メンターの方が沢山いて質問しやすくて良かったです」などなど、嬉しい反応が投稿されていました!
これからもGoハンズオンを開催予定ですので、ご興味のある方はお気軽にご参加ください。
イベント告知・参加募集はconnpassより行なっております!

techdo.connpass.com

*1:The Go gopher was designed by Renée French.