[Go言語]Interfaceを学ぼう~net/httpパッケージを理解する~

こんにちは。KOUKIです。

とあるWeb系企業でエンジニアをやってます。

以前、Interfaceに関する記事を出しました。

この記事は、Interfaceの使い方に関して初級者から中級者になることを想定した記事です。

Interfaceはめちゃくちゃ便利なのですが、使い方が難しく、また実戦で活用しにくい機能の一つかと思います。

そこで、Goの標準パッケージである「net/http」を題材に、Interfaceをより理解することを目的にこの記事を書きました。

net/httpパッケージとは

net/httpパッケージは、HTTPのClientとServerの機能を提供します。

Exampleから簡単な例を取り上げましょう。

上記のコードは、http://www.google.com/robots.txtに対してGetリクエストを送り、その結果をコンソール上に表示します。

簡単にHTTP Getリクエストを行えるプログラムが作成できるわけですね。

もちろん、サーバーも作れます

上記のコードは、8080番ポートでリッスンするFileサーバーです。

Handlerが大切な件

net/httpパッケージを理解する上で、最も大切なものの一つがHandler Interfaceでしょう。

このHandler Interfaceはnet/httpパッケージ内の至る所で使われています。

ちなみに、ServeHTTPは、リクエストの応答を呼び出し元に返す機能を提供します

例えばですが、Serverを立ち上げるとき、以下の処理を呼び出します。

どちらの処理も引数にHandler Interfaceを渡すことになっています。

そして、このHandller Interfaceには「ServeHTTP」メソッドが実装されることになっており、これを使って呼び出し元にリクエストを返す流れになります

ResponseWriterとRequest

Handler InterfaceのServeHTTP関数は、「ResponseWriter(レスポンス)」と「Request(リクエスト)」を持っています。

Requestは呼び出しもとからの情報が格納されるStructであるとして、注目したいのがResponseWriter Interfaceです。

ResponseWriter Interfaceは、「Header」、「Write」、「WriteHeader」関数を持っており、名前からして処理結果を呼び出しもとに返すためのものと想像できます。

これらの機能を実装したものであれば、自作したメソッドもServeHTTP関数に渡せそうですね。

Handler Interfaceを紐解くと、こんな感じになっています。

Handlerを作成しよう

Handlerを実装してみましょう。

まずは、Handler Interfaceのシグネチャを思い出してください。

このInterfaceは、「ServeHTTP(ResponseWriter, *Request)」(シグネチャ)を持っています。つまり、これを満たすメソッドを作成するとHandler Interfaceを実装したことになります。

bookmanを宣言し、「ServeHTTP」メソッドを実装しました。これでHandler Interfaceの要件を満たすので、ListenAndServeメソッドの第二引数に渡すことができます。

下記のコマンドで、サーバーを立ち上げましょう。

サーバーは、「8080番ポート」をリッスンします。

ブラウザから「http://localhost:8080」にアクセスしてみましょう。

OKですね。問題なくサーバーが起動してます。

Client-Serverを構築してみよう

net/httpパッケージの至る所で使われる「Response」についてもう少し掘り下げます。

公式では、「Response represents the response from an HTTP request.(ResponseはHTTP Requestからのレスポンスを表す)」とあります。

サーバー側でリクエストを受け取った後、任意の処理を実行し、結果を呼び出しもとに返す。その際に必要なものがResponseです。

そして、これが「Client – Server」のアーキテクチャとなります。

処理結果を返却する際は、HTTPプロトコルやコミュニケーションルールなども合わせて返されるのでブラウザとの通信が可能になっています。

Go言語だけで、このアーキテクチャを実装できるので、実装してみましょう。

Web画面を作る

以下のファイルを作成してください。

「form.gohtml」には、Goのテンプレートファイルを書き込みます。

上記のHTMLの中には、「{{if .}}」など見慣れない構文があると思います。

これは、Go言語の標準パッケージである「text/template」の構文で、Go言語で処理した結果をHTMLのテンプレート内に埋め込むことができます。

VS Codeのおすすめなプラグインを下記の記事で紹介してます。

アプリケーションサーバーを作る

form.gohtmlはGoコードから読み込んで使います。先ほど実装したbookmanサーバーを拡張しましょう。

Goのコードからテンプレートを読み込むために、init関数でform.gohtmlをパースし、tpl変数に格納してます。

それをServeHTTPメソッド内で、リクエストと共に呼び出しもとに返す処理を追加実装しました。

req.Formには、Formから渡された値が入ります。

動作確認

下記のコマンドで、bookmanサーバーを起動します。

そして、ブラウザから「http://localhost:8080」にアクセスします。

nameテキストボックスに「j.k. rowling」と打ち込んで、「User submit」を押下してみましょう。

続いて、book nameテキストボックスに「Harry Potter」を打ち込んで、「Book Name Submit」ボタンを押下してみます。

OKですね。Interfaceを実装した自分のHandlerで問題なく処理が行えていることがわかりました。

補足:詳細なデータ回収

reqパラメータにはたくさんのリクエスト情報が格納されているので、下記のような感じでデータ収集可能です。
※ テンプレートを直さないといけませんが…

まとめ

簡単でしたが、以上です。

Interfaceを活用すれば、柔軟なプログラミングが行えることをお分かりいただけた、、、と思います^^

プログラムの密結合も防げるし、慣れればGoのコードもより読みやすくなります。

ただし、ソースコードを追うのがちょっと難しくなりますが…笑

ガンガン使ってより上級者になりましょう。

それでは、また!

Go言語まとめ

まとめ記事


コメントを残す