初めまして、ドリコムにてサーバサイドエンジニアをしております hayabusa333 (橘田)です。
こちらの記事はElixir Conf Japan 2017のレポート第1回目となります。
2017年4月1日に Elixir Conf Japan 2017が開催され、LTにて「APIサーバーとしてのCowboy」というタイトルで登壇させていただきました。

資料

当日の資料はこちらとなります。

APIサーバーとしてのCowboy
https://speakerdeck.com/hayabusa333/apisabatositefalsecowboy

Cowboyについて

CowboyはErlangで書かれた軽量なWebサーバとなっています。

Cowboyの1.0がリリースされたのが2014年8月1日となるようです。
ElixirConfJapanが開催された2017年4月1日時点では1.1.2が安定版としてリリースされており、メジャーアップデート版として2.0.0-pre7がリリースされておりました。
また4月18日に2.0.0-pre8がリリースされ、2.0.0の開発はまだ続いているようです。

Phoenixについて

PhoenixはElixirで書かれた信頼性と高速であり生産性のたかさをうたっているWebフレームワークです。
こちらは1.2.1が現在の安定版としてリリースされており、現在1.3.0のアップデートのため1.3.0-rc.0がリリースされ、1.3.0-rc.1がバージョンアップに向けて開発が動いております。
また、1.3.0からは内部のディレクトリ構成が変わっていますので下記で記載されているディレクトリ構成とは違いますので注意が必要です。

ディレクトリ構成

Elixirでは新規に何かを作る際にはmix newによって作成を行っていきます。mix newした場合のディレクトリ構成は下記となります。

.
├─ config  : 設定ファイル類
├─ lib        : ソースコード
├─ mix.exs : mix管理設定
└─ test      : テストコード

PhoenixはMix.Custom.Taskを利用してPhoenix独自のコマンドとしてmix phoenix.newがあります。
Phoenix 1.2.1 以前のバージョンにてmix phoenix.newをした場合のアプリケーションのディレクトリ構成は下記となります。

.
├─ brunch-config.js : brunch の管理用JavaScript
├─ config
├─ lib
├─ mix.exs
├─ package.json      : Node管理用json
├─ priv                    : 外部公開しない migration、css、js 管理用
├─ test
└─ web                    : アプリケーションのコード管理用
    ├─ channels         : チャネルを管理用
    ├─ controllers      : コントローラーの管理
    ├─ models           : モデルの管理
    ├─ router.ex        : ルーティングを記載するコード
    ├─ static             : スタティックファイル管理
    ├─ views             : ビューの管理用

Phoenixでは、独自のコマンドを実装しており、フレームワークとしてディレクトリの型を用意しております。
CowboyをElixirで使用する場合には、ElixirからMixを使用してCowboyを使用するように設定を行いますが、Cowboy自体に決まったディレクトリ構成などは存在しておりません。
そのため知らなければどのように作っていくこともできるといえばできるので注意が必要です。
それに比べてPhoenixではディレクトリ構成が決まっていますので、その形に合わせて作成して行く必要があります。
またCowboy自体もPhoenixのようなディレクトリ構成にあわせることもでき、私も参考にしながらディレクトリを切っていたりします。

View

表示周りに関してですが、CowboyはWebサーバとして実装を行えばHTMLやCSSやJavaScriptをブラウザに送ることができます。
何度も書いていますがCowboy自体はサーバですので、HTMLを返すことはできてもサーバ内部で使用している変数などを使用してHTMLを良い形に変更してくれることはできません。
そのあたりはPhoenixを使用するか、phoenix_htmlを使用すればCowboyでもできるとは思われますが、それであるならばPhoenixを使用するのが良いと思います。
Cowboyでフロントをきっちりと行いたいのであるならば、JavaScriptに対してJSONなどを返すAPIサーバとHTMLを返すWebサーバをルーティングで切り替える使い方が良いと思います。

Model

ElixirでDBを操るのであるならばEctoを使うのがよく、Ectoが標準でPostgreSQLにアクセスできるのでPostgreSQLを用意するのが良いかと思います。
ただしEctoは他のDBにもアクセスできますので、DB自体は特に気にする必要はないかと思います。
Ectoにはマイグレーション機能も用意されていますし、アクセス自体もCowboyであろうがPhoenixであろうが特に違いはりません。
最近のPhoenixですとEctoの挙動を内部に隠すように実装が変更されていたりしますので、そのあたりは嬉しい感じになってきています。

速度

Phoenixの内部ではCowboyが動いているため、単純に動かした場合にはCowboyのほうが速いです。
ただしアクセスする数によってはプロセスの作成であったり、IOの制限によりCowboyの方が遅い場合もあります。
このあたりはサーバの動いているOSのチューニングであったり、Erlangのチューニングを行う必要がありますが、まとまった情報がない分野でもありますので1つずつためして行くしかない部分です。
しかしアクセス数が増えなければ問題が無い部分でもありますので個人で使うぶんには気にしなくても良かったりします。

まとめ

Phoenixはもちろんのことですが、CowboyでもWebアプリケーションを作っていくことはそれほど難しくなく実装していくことが可能です。
しかしCowboyでView周りを頑張るよりは別のアーキテクチャに任せてしまうのが良いと感じております。
CowboyにWebアプリケーションの動作を記載するHandler部分に関しましてはコードの切り分けができますが、ルーティングに関してはある程度まとめれますが肥大化は逃れられないかと思います。
その辺りに関してはルーティングはルーティングとして切り分けているPhoenixの方が分割しやすいのかなっと感じております。

最後に

今後のElixirのより良い発展を願いつつ、Elixir界隈に少しでも貢献できるように自助努力してまいりますので宜しくお願いいたします。

About the Author

橘田 隼一

Junnichi Kitta

サーバーサイドエンジニア

2017年ドリコム入社。サーバーサイドにてアプリケーションの開発をしています。
RubyとElixir界隈に出没する錬金術師