先日 Go で API サーバーを開発してきて1年が過ぎました という記事を書きました。昨日、Go 1.7 がリリース されなかった (もとは8/8がリリース予定だったのが8/15に延期された) わけですが、そのリリースパーティが行われました。先日のブログに関して話してほしいという依頼を頂いたので発表してきました。運営の方々、発表の場を頂いてありがとうございました。
発表のスライドは以下になります。発表全体として (前回のブログのフォローする発表でもあったため) Go そのものは関係なく設計の話が中心になってしまいました。
※ How to Include Clickable Links on Slideshare Presentation によると、スライドの最初の3枚はリンクをクリックして遷移できないそうです (4枚目以降は遷移できる) 。最初の3枚のリンク先に興味がある方は PDF をダウンロードしてください。
スライドで紹介した WEB+DB PRESS Vol.74 の特集記事なのですが、正式には「Web 開発1年目に身につけたい 良い設計の基礎知識 変化に強い構造・読みやすいコード・適切な分割」というタイトルが付いています。当時、私はこの特集の著者が CTO を務める会社で働いていたわけですが、これらの基礎知識を身につけてはいませんでした。その会社での開発を通してそういった基礎知識が身につきました。さらに余談なんですが、当時この特集を読んだ後に個人ブログに所感を書いて本雑誌を紹介しようと草稿はほとんど完成していたものの、なぜか公開するのを数カ月ほど忘れてしまい、公開するタイミングを逃して結果的にその草稿を削除してしまいました。
あれから3年以上経ってしまいましたが、記事を紹介して知識も身につける (実践に活かす) ことができました。義理も果たせて義務も果たしたようで気分が良いです。
全体の発表が終わった後に @deeeet さんと話していてテストはどうしてます?といった質問を受けました。私は net/http のテストコードを参考にしながら TableDrivenTests を書いています。例えば、以下のようにしてレスポンスやリクエストを生成できます。net/http/httptest というテスト向けのユーティリティパッケージもあるので使えるものはそのまま使うと良いと思います。
res := httptest.NewRecorder() req := new(http.Request) req.URL = &url.URL{Path: "/api/ping"} req.Method = "GET" req.Header = make(http.Header) req.Header.Set("Content-Type", "application/json")
そうやって話していて気付いたのですが、レイヤ化して context を API 処理に渡すことのもう1つのメリットとしては単体テストが容易になることです。例えば、PingAPI というものがあって、その実装は以下のようになっているわけですが、API 処理は context としかやり取りしないので引数で渡している ApplicationContext を操作することでテストが書けます。
func PingAPI(c *types.ApplicationContext) { r := &PingAPIResponse{ CommonResponse: types.CommonResponse{Status: types.VALUE_OK}, Message: "pong", } c.SetResponse(r) }
私は Go 1.6 Release Party のときも参加していたのですが、リリースされた機会に新機能や変更点などを聞けるのは良いものですね。あまり他の言語コミュニティで見かけない気がします。今後もこのイベントが続いていくと嬉しいです。
最後に白ヤギコーポレーションでは一緒に API サービスを開発/運用してくれるエンジニアを募集しています。Go でプロダクト開発をしてみたい方、ぜひご応募ください。