これからGoのginでWebアプリケーションを作っていく過程を,自分が見返す用にここに記して残していく.わからない単語は直後に()で説明を入れていく.読みにくくなるが,下で箇条書きされているよりは理解が進みやすいと思うので,この方式で進めていく.
これからの記事が私と似たようなレベル感の方の一助になっても嬉しい.
まず今回使うバックエンド用のディレクトリを作成する.
mkdir backend
このmkdir
はmake directryの略.
次にbackendディレクトリに移動して,
go mod init github.com/shogonakamura1/Persk_go_version/backend
go get github.com/gin-gonic/gin
とする.
go mod init
はGoプロジェクトをモジュール(一つの大きなプログラムを分けて整理した部品・まとまり)として初期化するコマンドである.言い換えると,このフォルダを一つのGoプロジェクトとして認識させるという操作である.
そしてgo get
だが,これは外部のGoモジュール(ライブラリ)を取得・インストールするコマンドである.今回は,ginというWebフレームワークをネットから取得し使用する(依存関係を登録する)ということになります.
このコマンドを実行すると,先ほどのgo mod init
を実行した際に作成されたgo.modのファイルに自動的に
require github.com/gin-gonic/gin v1.11.0
が追加される
次にbackendのディレクトリ内にmain.goというファイルを作成するために
touch main.go
を実行する.
そしてその中身に
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello, Gin with Docker! :cocktail:")
})
r.Run(":8080")
}
を打ち込む.
import
の"net/http"
はHTTPステータスなどの標準定数で,HTTP通信を扱うパッケージ.HTTPプロトコルを使う機能の基礎を提供してくれるもの.
そしてmain()
の中は,
r := gin.Default()
でルータを作成する.Default
は2つの標準ミドルウェア(リクエスト処理の前後で共通処理を差し込む仕組み)を事前装着するもの.これを別々で書くと,
r := gin.New()
r.Use(gin.Logger(), gin.Recovery())
こうなる.
Logger
は各リクエストのメタ情報(ステータス,レイテンシなど)を標準出力に記録するもの.可観測性の基盤で,性能問題やエラーの一次診断に使う.
Recoverry
はハンドラ(Webサーバーで特定のURLにアクセスされた時実際の処理を行う関数)内でpanic(Goで致命的なエラーが起きた時の強制停止信号)が起きても,プロセスを落とさずに500 Internal Server Error
で返すもの.本番運用での可用性(サーバーやシステムが止まらずに動き続けられる能力)を確保をし,1リクエストの異常が全体停止に波及しないようにするためのもの.
r.GET("/", func(c *gin.Context) {
はルーティングの定義で,HTTP GETメソッドの/
にハンドラ関数を割り当てている.
c *gin.Context
はリクエストとレスポンスの入出力をまとめたオブジェクトで*gin.Context
を今後c
として扱うこと宣言している.Context
は英単語の意味そのままで,リクエスト情報やレスポンス出力などの情報が含まれているginパッケージに定義されている構造体である.
ここでgin.Context
のポインタ(*:アドレス)を使用している理由は三つある.
◯ 大きな構造体を毎回コピーしないため
→ハンドラ関数の呼び出しごとに構造体全体をコピーしていたらメモリを余計に使う.アドレスだけを渡すことにより,高速でメモリも節約できる.
◯ ハンドラ間で同じデータを共有するため
→Ginでは1回のリクエストごとにミドルウェア(各関数)を経由する.情報をコピーしていると前のミドルウェアで情報を変更した際に,情報のコピーはミドルウェア(情報の操作)の前に行うこともあるため,その変更後の情報を利用することができない.アドレスだとリアルタイムの情報を利用できる.
◯ ハンドラ内でレスポンスや状態を変更するため
→c.String()
やc.JSON
はContextの内部にあるレスポンスバッファ(サーバーがクライアントに返すデータを一時的にためておく場所)や情報フラグを更新するため,同じ構造体を直接操作しなければならない.上の理由と同じ感じ.
c.String(http.StatusOK, "Hello, Gin with Docker! :cocktail:")
のString
はContent-Type: text/plain; charset=utf-8で文字列を返すもの.http.StatusOK
はGoの標準ライブラリnet/http
で定義されているもので,200が代入されている.ここでは上記の文字列とともに成功コードをつけて返すという指示.
cocktail:
は絵文字表示のため無視して良い.クライアント側の解釈次第で文字として返る.
r.Run(":8080")
はアドレス8080でHTTPサーバーを起動するという意味.省略しても8080で起動する.
次回は今回Docker構築も行うので,その設定を記す.