目次
1. はじめに
たまに「このリクエストってどんなヘッダが付いてるんだ?」っておもう時ありませんか?
自分の場合はすでに運用されているサーバが、ログにリクエストヘッダが出ない設定なっていた時です。
というわけでサクッとサーバアプリケーションを開発したかったのでgo言語を選択しました。
go言語の標準パッケージ net/http
を使えば簡単にサーバを開発できます。
リポジトリはこちら。
まずは最低限サーバアプリケーションを開発する方法から紹介します。
2. go言語でサーバを実装する方法
まずは特定のパスでリクエストが来た時に実行される処理を登録します。
登録したい処理は、関数として実装します。
引数は第一引数が http.ResponseWriter
型で、第二引数が *http.Request
型です。
この第一引数にたいして書き込みを行うことでレスポンスを構成していきます。
たとえば "ok"
を返すだけだったら次のような関数を実装します。
func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "ok") }
次にこのハンドラーをリクエストパスに紐付けます。
下記のソースコードの通りに書くだけでサーバが起動します。
ポート番号が7999で、 /gora/
から始まるパスに来たら hander
関数が実行されます。
package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "ok") } func main() { http.HandleFunc("/gora/", handler) err := http.ListenAndServe(":7999", nil) if err != nil { fmt.Println(err) } }
3. リクエストのパスを取得する方法
リクエストのパスは、 http.Request
型のインスタンスから取得することができます。
.RequestURI
とすると、ポート番号より後のURIが取得できます。
http://localhost:7999/gora/ping
とリクエストした時は、
.RequestURI
は /gora/ping
になります。
4. リクエストのヘッダを取得する方法
リクエストヘッダも http.Request
型のインスタンスから取得することができます。
.Header
とすると、リクエストヘッダを map[string][]string
のような型です。
5. 動作確認
最終的なソースコードは下記のようになりました。
package main import ( "flag" "fmt" "net/http" "strconv" "time" ) func strfNow() string { now := time.Now() const layout = "2006-01-02 15:04:05" return now.Format(layout) } func suffix(iter int, length int) string { if iter == length { return "\n" } else { return ",\n" } } func displayHeaders(headers http.Header) { fmt.Println("\"headers\": {") iter, length := 0, len(headers) for key, value := range headers { iter++ fmt.Printf(" \"" + key + "\":\"" + value[0] + "\"" + suffix(iter, length)) } fmt.Println("}") fmt.Println() } func handler(w http.ResponseWriter, r *http.Request) { fmt.Println(strfNow() + " " + r.RequestURI) displayHeaders(r.Header) fmt.Fprint(w, "ok") } func main() { port := flag.Int("port", 7999, "listen port number") flag.Parse() fmt.Println() fmt.Println("'gora' has started.") fmt.Printf("listening: ':%d/gora/*'\n\n", *port) http.HandleFunc("/gora/", handler) err := http.ListenAndServe(":"+strconv.Itoa(*port), nil) if err != nil { fmt.Println(err) } }
完成したので動作確認を行いたいなと思います。
ポート番号を8000に指定してサーバを起動してみます。
$ go run gora.go --port 8000 'gora' has started. listening: ':8000/gora/*'
別のターミナルでリクエストを送ってみます。
$ curl "http://localhost:8000/gora/ping" ok
レスポンスボディに ok
が返ってきているのがわかります。
その時 gora
の方のターミナルにはリクエストヘッダが表示されています。
2019-12-02 19:35:43 /gora/ping "headers": { "User-Agent":"curl/7.64.1", "Accept":"*/*" }
6 さいごに
今回はgo言語でサーバアプリケーションを実装してみました。
使ってみて、go言語の net/http
が非常に優秀なので、
ちょっとしたサーバ開発にはすごくおすすめです。
しかも別の環境で動かしたくなった時もgoなら安心です。
みなさんもgoで何かを開発してみてはいかがでしょうか。