🐙

RubyistのGolang入門記 - echo編

2023/12/13に公開

はじめに

本記事はプロもくチャット Advent Calendar 2023の13日目です。

https://qiita.com/advent-calendar/2023/puromoku

前回のあらすじ

Ruby歴2年半のエンジニアが初めてGoを触ることになったため、急遽キャッチアップを始めました。

ChatGPTに提案してもらった学習プラン通り、まずはA Tour of Goを完走しました。

https://zenn.dev/shu_illy/articles/d8e43a17723046

ChatGPT

echo

続いてechoの学習です。

公式ドキュメントに簡単なハンズオンがあったので、こちらをやってみました。

https://echo.labstack.com/docs/quick-start

環境構築

A Tour of Goではブラウザ上のプレイグラウンドを使ってコードを書いていたので、ここで初めてローカルの環境構築を行いました。

Golangインストール

各言語のバージョン管理ツールにrtxを使っているので、rtx上にGolangをインストールしました。
rtxはRustで開発されていて、asdfとも互換性があります。

rtxについてはこちら↓

https://github.com/jdx/rtx

https://zenn.dev/mukanakazato/articles/084964315ccb8e

安定版(2023/12時点)の1.21.5をインストールします。

$ rtx install go@1.21.5

Golang 1.21.5がインストールされていることを確認します。

$ go version
go version go1.21.5 darwin/arm64

プロジェクト作成

echoハンズオン用のプロジェクトを作成し、echoをダウンロードします。

$ mkdir echo_tutorial && cd echo_tutorial
$ go mod init echo_tutorial

go mod initコマンドで生成されるgo.modファイルは、モジュールの依存関係などを示したファイルです。
Rubyで言うところのGemfileのような役割です。

go.mod
module hoge

go 1.21.5

次に以下のコマンドでechoをインストールします。

$ go get github.com/labstack/echo/v4

go.modが以下のように更新され、go.sumというファイルができました。
go.sumはモジュールの依存関係をハッシュ化したものを保存したファイルで、Gemfile.lockと似たような役割を持ちます。

go.mod
module hoge

go 1.21.5

require (
	github.com/labstack/echo/v4 v4.11.3 // indirect
	github.com/labstack/gommon v0.4.0 // indirect
	github.com/mattn/go-colorable v0.1.13 // indirect
	github.com/mattn/go-isatty v0.0.19 // indirect
	github.com/valyala/bytebufferpool v1.0.0 // indirect
	github.com/valyala/fasttemplate v1.2.2 // indirect
	golang.org/x/crypto v0.14.0 // indirect
	golang.org/x/net v0.17.0 // indirect
	golang.org/x/sys v0.13.0 // indirect
	golang.org/x/text v0.13.0 // indirect
)

エディタ設定

とりあえずGoの拡張機能を入れておけばよさそうです。

https://marketplace.visualstudio.com/items?itemName=golang.Go

他にも色々拡張機能ありますが、必要に応じて追加していくようにしたいと思います。

次に、VSCodeでGoツールを更新します。

Cmd + Shift + Pでコマンドパレットを開き、Go: install/Update Toolsを実行し、表示される全てのツールを選択、[OK]をクリックします。

update tools

エントリーポイント作成

server.goファイルを作成します。
Golangでは、mainパッケージ内のmain関数がエントリーポイントとして実行が開始されます。

このサンプルでは、rootパス(/)へのGETリクエストを定義しています。

Railsでのroutes.rbとcontrollerをまとめて定義しているようなイメージです。

Railsの学習を始めたばかりの頃は、routesとcontrollerの関連がいまいちよく分かっていなかったものですが、こちらはとてもシンプルですね。

server.go
package main

import (
    "net/http"
    
    "github.com/labstack/echo/v4"
)

func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, World!")
    })
    e.Logger.Fatal(e.Start("localhost:1323"))
}

サーバーを起動します。
Railsでのrails serverコマンドのようなものです。

$ go run server.go

server

localhost:1323にリクエストを送ると、"Hello, World!"というレスポンスが返ってきました。

$ curl http://localhost:1323
Hello, World!

ルーティング追加

rootパスへのGETリクエスト以外にもルーティングを追加します。

server.goに以下の記述を追加します。

e.GET("/users/:id", getUser)
func getUser(c echo.Context) error {
    // User ID from path `users/:id`
    id := c.Param("id")
    return c.String(http.StatusOK, id)
}

contextから上記のようにパラメータを取得できます。
ここではURLのパラメータを取得していますが、クエリパラメータやリクエストボディやPOSTリクエストのボディも取得できます。

$ curl http://localhost:1323/users/taro
taro

echoにはミドルウェアの機能もあり、リクエストやレスポンスに対して処理を差し込むことができます。

今の所、サーバーを起動したコンソールではリクエストを送っても何もログが表示されていませんが、ミドルウェアを使ってログが表示できます。

server.go
package main

import (
	"net/http"

	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware" // 追加
)

func main() {
	e := echo.New()

	e.Use(middleware.Logger()) // 追加

	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})
	e.GET("/users/:id", getUser)
	e.Logger.Fatal(e.Start("localhost:1323"))
}

func getUser(c echo.Context) error {
	// User ID from path `users/:id`
	id := c.Param("id")
	return c.String(http.StatusOK, id)
}

これで先ほどと同じリクエストを送ってみます。

$ curl http://localhost:1323/users/taro

log

無事にログが表示されました。

まとめ

文字列を返すだけの非常にシンプルなものですが、このように簡単にサーバーを立ち上げることができました。

まだまだ触りの部分でしかありませんが、何となくGolangやechoがシンプルと言われる所以を感じられたような気がします。

次はGolangにおけるORM(RailsのActiveRecordのようなもの)として、GORMを使ってみようと思います。

最後までご覧いただきありがとうございました。

Discussion