goa でデザイン・ファーストをシュッとする

# はじめに

この記事は Go(その3) Advent Calendar の19日目の記事です。

[goa.design](https://goa.design/)(以下 goa)の紹介をしたいと思います。

goa は APIデザインを書くと、そこから API サーバのモックとかクライアントとかドキュメントとか一通り生成してくれるマイクロサービス用のフレームワークのことです。

goa は APIデザインを書いて → レビュー → 実装 → デザイン見直し → ・・・ とサイクルを回して開発するプロセスをとれるようにできています。まずは API デザインを書くことで見通しよく進めよう、というのが goa を利用する際の設計方針です。

![image](https://qiita-image-store.s3.amazonaws.com/0/44487/f8076b47-f382-6ac1-e15e-7c094a898056.png)

とてもすばらしいプロダクトなのですが、goa という名前のググラビリティが非常に悪く、なかなか広まらないなーと記事を書いたりしてました。最近、ちょっとずつですが goa のよさが広がってきていて(?) Advent Calendar にもいくつか記事が上がっています :raised_hands: 

* 17日目 : [これからMicroservicesな開発をするならgoaがおすすめという話](http://qiita.com/y_matsuwitter/items/1298adfcd26c84f7d20b)
* 18日目 : [Swagger 定義から goa の design を生成する ago という CLI を作りはじめた](http://tchssk.hatenablog.com/entry/2016/12/17/211443)

# goa 流行らない問題

@tchssk さんも[言及](http://tchssk.hatenablog.com/entry/2016/12/17/211443)されてますが、goa は何故か(?)流行らない。goa の仕組みは自体はいたって単純で、

* API定義(デザイン)を go のコードで書く。func()を駆使した DSL。だけど go のコードとして正しい。
* API定義(デザイン)から `goagen` コマンドで必要なものを生成。
 * サーバのモック
 * swagger定義(ドキュメント)
 * クライアント etc... が生成可能

をするだけです。生成されたサーバのモックでは、パラメータのバリデーションなどはAPI定義に従って正しく処理されるようになっているので、必要なのは本当にビジネスロジック部分だけになります。

## そもそもドキュメント書かないという衝撃

慣れてしまえば非常に便利なんですけれど、やはり DSL を書かなきゃいけないのは敷居が高いのかなと思います。しかし、一緒にドキュメントが生成されるのでドキュメント書く必要から解放され、仕様変更にも素早く対応できます。これは僕がホントに goa 使ってて良いなと思ってるところなんですが、ちょっと聞いたところ、

**そもそもドキュメント書かないところ多いですよ**

という衝撃の発言を耳にしました orz。もし、ドキュメント書いてないAPIがいっぱいあるのでしたら、是非 goa 導入してドキュメントも生成しましょう・・・。

## DSL 覚えたくない

あと、DSL 覚えたくないというのはもっともだと思うんですけど、APIサーバ書くのに必要な要素を薄いフレームワークで忘れずに網羅するのって結構難しいと思うんですよね。パラメータのバリデーションとか、エラー処理のときのステータスとか、レスポンスの形式とか、そういったことを一揃いちゃんと書くにはオレオレでやるより枠組みがあったほうが抜けがなくなります。

goa の DSL はAPI定義に必要最低限なものが用意されているので、覚えておくと、サービスにどういった要素が必要かと言うことを常に意識できるようになると思います。僕のおすすめは [Web API The Good Parts](http://amzn.to/2gNHqYx) と一緒に DSL を読んでいくと Web API 自体に理解が深まっていくのでおすすめです。

<a href="https://www.amazon.co.jp/Web-API-Parts-%E6%B0%B4%E9%87%8E-%E8%B2%B4%E6%98%8E/dp/4873116864/ref=as_li_ss_il?ie=UTF8&linkCode=li2&tag=foxii-22&linkId=1458b243d91b6c3af14d305c078d2796" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4873116864&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=foxii-22" ></a>

swagger 定義がすでにあるようでしたら、@tchssk さんによって [swagger 定義から goa の DSL に変換するプロジェクトが進行中](http://tchssk.hatenablog.com/entry/2016/12/17/211443)なので、こちらを利用していただくのが良いかもしれません。

> design を構成するDSLの 1/3 程度は既にサポートしているので既存の Swagger 定義がある場合は goa 導入の助けになると思います。鋭意開発中なので近日中にすべてのDSLがサポートされる予定です。

とのことなのでｷﾀｲです！

## API 書く機会少ない

そもそも API を書く機会少ないという問題もあります。もし、新規で API 書く機会があれば、ぜひ goa を検討してみてください。

# goa の現在

goa はつい先日（2016/12/9） v1.1.0 がリリースされました :tada: → [Announcing goa v1.1.0](https://goa.design/blog/003-v1_1_0/)

goa では `master` と `v1` ブランチの2つのブランチで開発が進められていて、`v1`ブランチがv1.x.x リリースと対応しています。`master` ブランチは BREAKING CHANGE を含むような機能追加などを含む最新のバージョンになります。といっても、`master` ブランチもそれほどv1.x.xと変わらないので、`master` ブランチをvendoring しながら使うのでもそれほど問題は起きない気はします。

もし、goa に修正を pr する機会があれば、`v1`と`master`の両方に pr を出してあげてください。goa の開発者の Raphael さんは Contributor を非常に大切にされる方で、ちょっとした pr でも `great!` とか `awesome` とか最大限励ましてくれて癒やされます。さらに、リリースの時には、contributor をリリースノートに記載してくれたりして、ホントもう「また pr してまうやろー」とWエンジンぽく叫びたくなります。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Who wants stickers? <a href="https://t.co/02viBYRxkc">pic.twitter.com/02viBYRxkc</a></p>&mdash; Raphael Simon (@rgsimon) <a href="https://twitter.com/rgsimon/status/752508389490511872">2016年7月11日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">goa ステッカーを手に入れたぞ！<br>Thanks for sending me the stickers <a href="https://twitter.com/rgsimon">@rgsimon</a> <a href="https://t.co/g4iKSDiyKb">pic.twitter.com/g4iKSDiyKb</a></p>&mdash; ikawaha@goaおじさん (@ikawaha) <a href="https://twitter.com/ikawaha/status/757729597978845184">2016年7月26日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

Raphael さん、ほんといい人で、ステッカー送ってもらったりしちゃいました。

# goa のこれから

goa では gRPC の対応に向けて v2 が進行中です。v2 は `v2` ブランチで開発が進行中ですが、やっと DSL がそろってきてテストを書き始めたという段階のようです。gRPC を使った API もデザイン・ファーストで構築できるようになると用途が広がってきそうですね。

とはいえ、v2 が使えるのはまだちょっと先になりそうなので、これから goa を利用するなら `v1` か `master` を使うことになりそうです。

# 勉強会してみました

goa 流行らせたいなと思って、goa を紹介する勉強会開催してみました。この勉強会をきっかけに goa を使ってみてくれた人もいたみたいなのでやってみた甲斐があったかなと :muscle:。

[golang: goa勉強会を開催しました](http://ikawaha.hateblo.jp/entry/2016/09/07/175820)

初めて自分で開催してみたんですが、勉強会って大変ですね（こなみ）。資料も作ったんですが早口で1回しかお話しできてないんでちょっと消化不良気味です。goa に興味があってちょっと話ききたいなーって人がいらっしゃいましたら、 goa シール持って駆けつけたいと思いますのでご連絡ください :ok_woman:

日本語で情報交換できるように gopher slack に goa-jp というチャンネルを作ってますので、こちらで質問していただければ、誰かが何か答えられるかなと思います。

https://gophers.slack.com/messages/goa-jp/

まだ gopher slack に参加してない方はこちらから！ → https://invite.slack.golangbridge.org/

# 書きためた記事のご紹介

最後に、これまで書いた goa の記事をまとめておきます。これからも少しずつ書き足していきたいと思います。

1. [goa をはじめよう](http://ikawaha.hateblo.jp/entry/2016/09/11/095129)
2. [goa のインストールと実行](http://ikawaha.hateblo.jp/entry/2016/09/12/164728)
3. [goa の API デザインの書き方 前編 (API と MediaType)](http://ikawaha.hateblo.jp/entry/2016/09/13/215006)
4. [goa の API デザインの書き方 後編 (Resource と Payload)](http://ikawaha.hateblo.jp/entry/2016/09/14/194237)
5. [goa tips : Attribute と Param と Member は同じもの](http://ikawaha.hateblo.jp/entry/2016/09/14/200606)
6. [goa tips : Type と MediaType を使い分けよう](http://ikawaha.hateblo.jp/entry/2016/09/15/235913)
7. [goa tips : swagger-ui を使って手っ取り早く API を試す](http://ikawaha.hateblo.jp/entry/2016/09/21/172336)
8. [goa の controller を実装する](http://ikawaha.hateblo.jp/entry/2016/10/11/234941)
9. [goa tips: swagger-ui がサービスできないときのドキュメントどうする問題](http://ikawaha.hateblo.jp/entry/2016/10/20/102425)
10. [goa tips: 小ネタ (swaggerドキュメントの抑制とパラメータ必須要素について)](http://ikawaha.hateblo.jp/entry/2016/12/18/124825)

それでは、Happy Hacking! よいお年を。