Goのnet/httpパッケージでHello WorldするだけのWebアプリ
本記事の目的
Goを学ぼうかどうか判断するために、簡単なWebアプリを作ってみます (アクセスしたら、Hello Worldと表示するだけ)。
開発環境
Goを信用して良いのか分からなかったので、環境を汚さないために、Dockerでやります。 面白かったら、デバッカーとかで内部まで見たいので、ローカルで環境構築します。
ディレクトリ構成は以下のようにしました。 compileFileディレクトリ内にgoファイルを置いて、ビルドしていきます。
compileFile (ディレクトリ) Dockerfile docker-compose.yml
# Dockerfile FROM golang:latest RUN mkdir -p /go/src
version: '3' services: go: build: . ports: - "8080:8080" volumes: - ./compileFile:/go/src working_dir: /go/src
コンテナ内に入って、goのコマンドを確かめてみます。
--service-portsを指定しないと、8080ポート同士を繋げることはできないので、注意です。
docker ps
でちゃんとポートフォワードできていることを確認しておきます。
$ docker-compose run --service-ports go /bin/bash $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af4f9c066ecd golean_go "/bin/bash" 7 seconds ago Up 2 seconds 0.0.0.0:8080->8080/tcp golean_go_run_a79a836040ab
ひとまず、go
と打ってみて、使えるコマンドを確認します。
Go is a tool for managing Go source code. Usage: go <command> [arguments] The commands are: bug start a bug report build compile packages and dependencies clean remove object files and cached files doc show documentation for package or symbol env print Go environment information fix update packages to use new APIs fmt gofmt (reformat) package sources generate generate Go files by processing source get add dependencies to current module and install them install compile and install packages and dependencies list list packages or modules mod module maintenance run compile and run Go program test test packages tool run specified go tool version print Go version vet report likely mistakes in packages Use "go help <command>" for more information about a command. Additional help topics: buildconstraint build constraints buildmode build modes c calling between Go and C cache build and test caching environment environment variables filetype file types go.mod the go.mod file gopath GOPATH environment variable gopath-get legacy GOPATH go get goproxy module proxy protocol importpath import path syntax modules modules, module versions, and more module-get module-aware go get module-auth module authentication using go.sum module-private module configuration for non-public modules packages package lists and patterns testflag testing flags testfunc testing functions Use "go help <topic>" for more information about that topic.
go build
go run
go fmt
は近いうちに使いそうです。
プロジェクト作成
馴染みが深いWebアプリからGoを理解していこうと思いました。 サンプルコードとか見ながら、Hello Worldをブラウザ上に表示するプログラムを書きます。
package main import "io" import "net/http" func mainHandler(w http.ResponseWriter, req *http.Request) { io.WriteString(w, `Hello World!!!`) } func main(){ http.HandleFunc("/main", mainHandler) http.ListenAndServe(":8080", nil) }
1コマンドで整形できるので、整形後ビルドします! ちなみに、ビルド時にリンターも働いているのか、改行の位置や使ってないパッケージがあると怒られます。
ビルドすると、goファイルのあるディレクトリ名の実行ファイルが作られました。
$ go fmt $ go build
$ ls server main.go $ ./server
http://localhost:8080/main にアクセスすると、Hello Worldを確認できました!
ちなみに、Macで動かしたい場合は、以下でMac用にコンパイルできます。
$ GOOS=darwin GOARCH=amd64 go build
net/httpパッケージ
わかりやすいところから見ていきます。 これでサーバーを立てられるようです。 第一引数がポートの指定、第二引数でHandlerを選択できるようで、nilの場合デフォルトのDefaultServeMuxが使われるようです。
http.ListenAndServe(":8080", nil)
DefaultServeMuxって何?
ドキュメントを読み進めると、以下の記述にあたります。
HandleFunc registers the handler function for the given pattern in the DefaultServeMux. The documentation for ServeMux explains how patterns are matched.
HandleFuncでURLのパターンに対応するハンドラーをDefaultServerMuxに登録できる...みたいなことが書いてあります。ルーティング的な何かと思っておきましょうか。
なので、以下は/mainにアクセスしたら、mainHandlerの処理を実行と読めます。
http.HandleFunc("/main", mainHandler)
ioパッケージの方は何してるか分かるので、置いておきます。
Localに導入
brewで簡単に入ります。
$ brew install go $ go version go version go1.15.3 darwin/amd64
REPLも入れておきます。 gore v0.5.0だと動かなかったので、バージョンを落としています。
# これをしてインストールできるようになりましたが、いらないかもです。 $ export GO111MODULE=on $ go get github.com/motemen/gore/cmd/gore@v0.4.0 $ gore -version gore 0.4.0 (rev: HEAD/go1.15.3)
間違えてインストールした場合は以下で削除できます。
$ go clean -i github.com/motemen/gore/cmd/gore
ちなみに、v0.5.0だと以下のエラーメッセージがでます。
gore: could not load 'fmt' package: err: exit status 1: stderr: build flag -mod=mod only valid when using modules
これでローカル環境も整ったので、あとは遊ぶだけです。
総括
Go楽しいですね。 ターミナルアプリ (TUI) とか作ってみたい。
雑多な感想
Qiitaで投稿しようかと思ったけど、Qiitaは怖い人ばかりで治安も悪いので、故郷のHatena Blogでひっそり過ごすことにした。