Go言語で簡単なWebサーバを作ってみた
最近Go言語の勉強しているので、書いたコードや学んだことを適当に
書いていきたいと思います。
最近はWebサーバを実装する方法について学んだのでそれについて書いていきます。
開発環境は以下の通り
- OS:Windows 10
- Goのversion:1.6
Goの環境構築はネットにたくさんあると思うので省略します。
Go使ってるうちに便利だなと思ったのが以下のコマンド
cd %GOPATH%
すぐGoの開発環境に移動できるので覚えておくと作業がスムーズになる。
単一のgoファイルでWebサーバを作成
GOPATH内にフォルダを作って、その中にmain.goを作成する。 main.goの中身は以下の通り
package main import ( "log" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(` <html> <head> <title>helloworld</title> </head> <body> Hello Go </body> </html> `)) }) // Webサーバを開始します if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal("ListenAndServe:", err) } }
作成したらmain.goのあるディレクトリで以下のコマンドを実行
go run main.go
これでWebサーバが立ち上がります。簡単でいいですね!
ソースコードに書いたとおりのHTMLが返って来ていることを
確認して見てください。
ListenAndServeメソッドではポート8080上でWebサーバを開始しています。
http://localhost:8080/
にアクセスすることでhttp.HandleFuncが実行されますので、
ResponseWriter.Writeによって、HTMLが返ってきます。
ここで書いてもらったコードはGoのソースファイルにHTMLをハードコーディングしたものですが、
見た目がちょっと汚いので、次の章でHTML部分をtemplateに分けて作ってみます。
templateを使ったWebサーバ
前の章でmain.goを作成したフォルダにtemplates
という名前でフォルダを作って
そのフォルダにhelloworld.htmlを作成します。
helloworld.htmlの中身は前の章で書いたHTML部分を持ってきます。
<html> <head> <title>helloworld</title> </head> <body> Hello Go templateにしました </body> </html>
先ほど作成したWebサーバとの違いが分かるように内容をちょっと変えています。
このtemplateを呼び出すようにmain.goを以下のように修正
package main import ( "log" "net/http" "path/filepath" "sync" "text/template" ) // templは1つのテンプレートを表します type templateHandler struct { once sync.Once filename string templ *template.Template } // ServerHTTPはHTTPリクエストを処理します func (t *templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { t.once.Do(func() { t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename))) }) t.templ.Execute(w, nil) } func main() { //ルート http.Handle("/", &templateHandler{filename: "helloworld.html"}) //Webサーバを開始します if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal("ListenAndServe:", err) } }
上記のように編集してからサーバを再起動すると、templatesの中に作った
HTMLファイルが表示されているかと思います。
テンプレートの読み込み部分ですが、sync.Once型のDoメソッド内部でテンプレートのファイル名が渡されています。
そしてsync.Once型のDoメソッドによりテンプレートは呼び出された時に1回だけコンパイルされます。(遅延初期化)
なので、サーバ起動時にtemplatesフォルダがなかったりテンプレートファイルがなかったりしても動作します。
ただ、ないテンプレートを呼び出そうとすると動かなくなりますが。
また、コンパイルは呼び出し時に1回だけなのでテンプレートを修正した後はサーバを再起動しない限り
反映されません。
まとめ
- Webサーバはmain.goとtemplatesフォルダという構成になっている
- templates内にはHTMLをテンプレートファイルとして配置
- http.ListenAndServeでWebサーバを立ち上げる
- sync.once.Doで遅延初期化を実現できる
参考にしている本
- 作者: Mat Ryer,鵜飼文敏,牧野聡
- 出版社/メーカー: オライリージャパン
- 発売日: 2016/01/22
- メディア: 大型本
- この商品を含むブログ (2件) を見る
今後も勉強を進めていくので、定期的にブログ更新していきます。