Swagger 定義から goa の design を生成する ago という CLI を作りはじめた

これは Go (その2) Advent Calendar 2016 の 17 日目の記事です。

ここ半年ほど goa というフレームワークを気に入って使っているのですが、思うところがあって goa に関連する ago という CLI を作りはじめました。この記事では、簡単な goa の説明から、今回の開発に至った経緯と、このツールで行えることについて記述します。

goa とは

Go でマイクロサービスな Web API を作るためのフレームワークです。

github.com

goa の DSL で design と呼ばれる定義を書いたら、 goagen というジェネレータを使ってサーバやクライアントなど各種のコードを生成することができます。毎度リンクを貼らせて頂いているのですが @ikawaha さんによる連載記事が本当にオススメです。

ikawaha.hateblo.jp

goa 流行らない問題

そうなんです。私も良さを広めたいユーザの一人なんですがなんか流行らないんです。参考までに他の Web フレームワークGitHub のスター数を比較してみました。 (2016/12/17 時点)

Repository Since Stars
https://github.com/gin-gonic/gin 2014/06/15 8294
https://github.com/labstack/echo 2015/03/01 6034
https://github.com/goadesign/goa 2015/10/18 1613

そして Google Trends の人気度推移。

開発が開始された時期の違いはあるにしてもあまりにも大きな差ですね。

ではなぜ流行らないのか。この理由を定量的に説明するのは難しいですが、おそらく goa のユニークな開発アプローチがその参入障壁を高くしてしまっているのだと思います。

  • 専用の DSL で design と呼ばれる設計書を書く
  • design を元にアプリケーションコードの大部分を自動生成する

goa での開発においてこれらのステップは必須です。避けて通ることはできません。 Go の Web フレームワークを net/http, gin, echo, ..., goa と横に並べて比較したとき、 goa の毛色が他と大きく異なることは明らかです。 Go を長く使っているユーザほど、それが「シンプルで、信頼でき、効率的なソフトウェアを構築しやすくする」という Go の思想に反していると感じてしまうかもしれません。

しかし一度 DSL を覚えてしまえばアプリケーションのインタフェース (リクエストとレスポンス) はすべて design に記述されているという見通しの良さが手に入りますし、大規模にコード生成を活用している点なども含めて実際は実に Go らしいフレームワークだと思います。

既存の Swagger プロジェクトの goa への移行問題

少し話は変わって Open API Initiative への採用も記憶に新しい Swagger です。実際に Swagger を使っているプロジェクトも増えているような気がするのですが、既存の Swagger プロジェクトを goa に移行したいというニーズがあるようです。

goa は標準で Swagger をサポートしており、 Swager の公式ページにも記載されています。しかし、そのサポートの意味は「 Swagger 定義の出力」であり「 Swagger 定義からのコード生成」ではありません。 goa は Swagger とよく似たワークフローを採用していますが、その中心にあるものが違います。 Swagger を用いた開発の中心にあるのは「 Swagger 定義」であり、そこからアプリケーションコードを生成しますが、 goa を用いた開発の中心にあるのは「 goa の design 」であり「 Swagger 定義」はアプリケーションコードと同じ生成物のひとつに過ぎないのです。

goa を用いる以上 design を中心に据えた開発を行う必要がある、しかし Swagger ユーザに goa への移行パスは用意したい、それを可能にするにはどうすればいいか。 Swagger 定義から goa の design を生成するコマンドがあれば Swagger ユーザはスムーズに goa を使い始められるのではないでしょうか。

ago

ようやく本題です。 ago というコマンドを作り (はじめ) ました。

github.com

使い方は簡単です。

$ ago swagger swagger.json > design.go

このように swagger.json を引数として渡すと標準出力に goa の design が出力されます。本当はきちんと完成させたかったのですが間に合わなかったため完全な design は出力されません orz しかし design を構成する DSL の 1/3 程度は既にサポートしているので既存の Swagger 定義がある場合は goa 導入の助けになると思います。鋭意開発中なので近日中にすべての DSL がサポートされる予定です。

あとがき

実際このツールのニーズはかなり局所的な気もしているのですが、既に Swagger を使っている方は試してみていただけたら嬉しいです。また何より、 goa に少しでも興味を持った方はこのフレームワークに触れてみて、その素晴らしさを体感してみて欲しいと思います。