BLOG株式会社ラクーンホールディングスのエンジニア/デザイナーから技術情報をはじめ、世の中のためになることや社内のことなどを発信してます。by一緒にラクーンのサービスをつくりませんか?採用情報カジュアル面談2017.2.1開発golangGo言語のWebサーバーフレームワークgojiの紹介golanggojiこんにちは、開発第2チームTabbyのイマガワです。Paidの開発を担当しています。最近社内の卓球大会で優勝しました。今回は、マイクロサービスをつくる機会があったので、それについて書きたいと思います。社内にGo言語の本を書いたエンジニアがいまして、本が出版されたばかりだったのでGo言語で実装してみました。Go言語の基本的なことは、そちらの本がおすすめです。net/httpパッケージでも簡単なマイクロサービスを作るには十分ですが、せっかくなのでフレームワークを使って実装してみたいと思いgojiを使ってみました。gojiの説明をする前に、net/httpパッケージの説明をします。net/httpパッケージの使い方net/httpパッケージではURLとハンドラの結びつきを簡単にするServeMuxを提供しています。ServeMuxはhttp.Handlerのコレクションを単一のhttp.Handlerへ集めます。ServeMuxは独自に定義することができ、特に指定がなければnet/httpパッケージが提供しているDefaultMuxが適用されます。DefaultMuxはREST対応していないので、HTTPメソッドによって処理を振り分けたい場合は、独自にServeMuxを定義する必要があります。http.ListenAndServeにnilを指定するとDefaultMuxが適用されます。ListenAndServeに起動Port、muxを指定して実行すると設定した内容に基づいて起動Portでリッスンした状態になります。DefaultMuxを使用した場合のコードをご覧ください。nil)}下記のコマンドで確認できます。World独自ServeMuxをつくる場合は、http.Handlerインターフェースを実装する必要があります。*Request)が定義されています。HTTPメソッドによって処理を振り分ける処理を実装します。独自ServeMuxを使用した場合のコードをご覧ください。mux)}下記のコマンドで確認できます。calledこれでnet/httpパッケージの説明を終わりにします。次はgojiの説明をします。github.com/zenazn/goji使い方ルーティングを設定して、処理を実装します。以下のことができます。goji.Serve()}下記のコマンドで確認できます。Testmiddlewaregojiはリクエストに共通した機能をmiddlewareという仕組みで共通化することができます。デフォルトで以下の4つの機能が追加されています。web.MiddlewareType)を使用して削除することができます。ユニークなリクエストIDを作成します。web.C)で作成したリクエストIDを取得できます。リクエストを受け取ったときとリクエストを返したときに以下のようなことを出力します。リクエストID、パス、HTTPメソッド、HTTPステータスコード等。デフォルトのログだけだと足りない場合はこのmiddlewareを削除して新規にmiddlewareを作成しましょう。内部エラーをキャッチします。エラーハンドリングが失敗した場合にHTTPステータスコードを500で返してくれます。HTTPメソッドのOPTIONがリクエストされた場合に使用可能なHTTPメソッドの一覧を返します。デフォルトでは何も返しません。簡単なサーバーにmiddlewareを追加してみます。goji.Serve()}下記のコマンドで確認できます。指定したパス以下にだけ認証処理など独自処理を実装したいことは多いと思います。いった場合はデフォルトのMUXだけでなく新しくMUXを追加して処理を実装します。middlewareパッケージ直下にあるSubRouterを使用します。SubRouterは対象のパス以下をまとめることができるmiddlewareです。下記のコードでは「/test」以下に処理をまとめています。goji.Serve()}下記のコマンドで確認できます。サーバープロセスの標準出力MyMuxMiddleware!!!シグナルを受け取った時の制御gojiはデフォルトでSIGINTを受け取りシャットダウンの前後の挙動を制御することができます。...os.Signal)で行うことができます。下記のようにシグナルを受け取った時の関数を定義します。もったWebAPIサーバーを作ってみます。それぞれHTTPメソッドPOST、GET、PUT、DELETEでアクセスします。認証はBasic認証で行います。json形式で結果を返します。ユーザ名:adminパスワード:admin事前準備データベースはMysqlを使用するので、Mysqlのインストールをしてください。Mysqlのドライバが必要になります。Mysqlのドライバは以下のコマンドを実行してください。github.com/go-sql-driver/mysqlDDL、DMLは以下になります。paid');COMMIT;データベース接続Mysqlへの接続の設定を行います。各環境に合わせた設定を行います。今回はシグナルを受け取った時にデータベース接続を閉じる処理を追加します。認証はBasic認証で行うのでヘッダを確認してユーザIDとパスワードが設定されているか確認します。設定されていない場合は、ユーザIDとパスワードを設定するようにレスポンスを返します。ハンドラを設定します。PutMember)レスポンスの作成json形式でアクセス結果を返します。Go言語には構造体をjson形式に変換してくれる標準パッケージ「encoding/json」があるので、そちらを使用します。Response構造体を定義します。Body.Messageはエラーメッセージや結果を格納できるようにinterface型で定義してあります。`json:"memberId"`}メンバー情報の構造体を定義します。MemberはBody.Messageに格納します。`json:"members"`}レスポンスの作成を行います。レスポンスの具体的な内容は以下のようになっています。リクエスト成功の場合はsuccess。string(result))}ソースコード下記に今回作成したソースコードの全文を載せておきます。正しいユーザID、パスワードを指定してください。"指定したIDをもつメンバーがいません。"メンバーの登録に失敗しました。"メンバーの更新に失敗しました。"メンバーの削除に失敗しました。FailAuthentication)}server.goをビルドして実行し、下記のコマンドを実行すると以下のような結果が得られると思います。"http://localhost:8000/member/1"{"header":{"status":"err"},"body":{"message":"認証エラー。正しいユーザID、パスワードを指定してください。"http://localhost:8000/member/1"{"header":{"status":"success"},"body":{"message":"","method":"DELETE","path":"/member/1","memberId":"1"}}gojiには紹介していない機能やmiddlewareがあるのでこれらを使ってみたり、自分で実装してみたりするとオリジナルなWebサーバーをつくることができます。gojiだけでなくgorilla、echoといった他のフレームワークもあるので、そちらを使ってみるのも面白いと思います。弊社ではあまりGo言語を使用した事例が少ないですが、Go言語の本の著者もいるので少しずつ取り入れていきたいと思います。