Akatsuki Advent Calendar 2016 12日目です。
Elixir で Web アプリケーションを書く場合、Phoenix がメジャーだと思います。
弊社でも直近でリリース予定のアプリケーションでは Phoenix を使いました。
今回は、テンプレートエンジンを使う、RDB を使う、などあって Phoenix にしました。
Web API を書く場合はどうでしょうか。
テンプレートエンジンが不要だったり、必要なものが減ると選択肢は変わるかもしれません。
テンプレートエンジン不要、WebSocket使う、RDB使わない、クライアントはUnity、
などの前提条件で、次の選択肢を検討しました。
- Phoenix を使う
- Plug の上に構築する
- Cowboy の上に構築する
Phoenix を使う
単純にプロジェクト作成を mix phoenix.new するといろいろ入ってきて、
Web API だけ作りたい人にとっては盛り過ぎ感があります。
なので、まずは Phoenix で Web API を書くのにどのくらいスリムに書けるかを追ってみます。
プロジェクト作成する
テンプレートエンジンも RDB も使わないと仮定すると、プロジェクト作成は以下で良さそうです。
mix phoenix.new sand --no-brunch --no-ecto --no-html
Static 関連を除去する
Static 関連は使わないので除去します。
priv/static/ 以下と、
lib/sand/endpoint.ex の Static 関連箇所を削除します。
View 関連を除去する
元は Controller から View にディスパッチする設計ですが、
それはテンプレートエンジンを使うことが視野に入っていると思うので、
API 作るなら View を分ける必要も強く無さそうです。
ということで除去します。
test/views/ 以下、
web/views/ 以下、
あと config/config.exs の該当箇所を削除します。
Gettext 関連を除去する
除去しましょう。
mix.exs
mix.lock
web/gettext.ex
priv/gettext/ 以下
あと web/web.ex の該当箇所を削除します。
Channel 関連を除去する
今回は WebSocket 使う予定なので Channel は使う前提ですが、
Channel も使わない場合は除去できます。
config/config.exs の pubsub の箇所、
lib/sand/endpoint.ex の socket の箇所、
mix.exs から phoenix_pubsub、
test/support/channel_case.ex
web/channels/ 以下を削除します。
またここまでで、
web/web.ex から model, view, channel の箇所を削除できます。
これで web.ex は controller と router だけになりました。
Plug.MethodOverride を除去する
Plug.MehodOverride は POST リクエストに _method パラメータで PUT, PATCH, DELETE という内容が含まれていた場合に、POST ではなくその METHOD だと上書きするための Plug です。
HTML の form を意識した Plug だと思います。
不要なので endpoint.ex から除去します。
Plug.Session を除去する
普通に API 作る場合は Session は不要なので除去します。
endpoint.ex から該当箇所を除去。
結果
ここまで削ると結果はこんな感じになります。
https://github.com/seizans/sand
web/ 以下や lib/sand/endpoint.ex がだいぶ少なくはなりました。
ここまでの感想としては、
だいぶコンパクトになったし良い感じなのではなかろうか、というのと、
果たしてここまでして Phoenix を使うメリットって何だったっけ?ということです。
Plug の上に構築する
次に Phoenix を使わずに Plug を使って構築することを検討しました。
思考の過程を端折って結論的な感想としては、
Plug で頑張ろうとすると結局 Phoenix みたく作り込むことになるので、
それなら Phoenix 使った方が素直で良さそうと思いました。
Cowboy の上に構築する
さてでは Cowboy ではどうかな、Cowboy はどこまでできるかな、を考えると、
https://ninenines.eu/docs/en/cowboy/2.0/guide/
- 普通にルーティングや API を書ける
- WebSocket を書ける
- 認証とかミドルウェアを書ける
- レスポンスをフックしてヘッダ付けるとかできる
という感じで、やりたいことはできるなという気持ちに。
できないこととしては、
テンプレートエンジンは組み込みでないし、
既存の middleware がいろいろ用意されているわけではないし、
Phoenix Channel のような WebSocket ラッパーがあるわけではない。
が、テンプレートエンジンは今回は使わないし、
必要な middleware は自分たちで書けばよい、
クライアントは Unity であり JS でないので phoenix.js を使えるわけではないので、
むしろ WebSocket は Phoenix Channel に縛られない方が助かりそう、
という感じで、できないことで特に困ることも私達にはなさそう。
結論
ということで Cowboy の上に構築する前提で進めています。