Phoneixとは、elixer(※1)という言語で書かれたWebフレームワークです。
最近のiOSやAndroidアプリやSPI(シングルページアプリケーショん)が普及してきたため、サーバーサイドはAPIやリアルタイムストリーミングの機能を提供することが増えてきました。
Phonixは一般的なWebのMVCに加え、デフォルトでAPIやソケットによるリアルタイムストリーミング機能を提供していて、このようなニーズに対応しやすくなっています。
レイテンシーがとても低く、Phoenixのレスポンスタイムはミリセカンドの代わりにマイクロセカンドで表示されるぐらい早さが段違いと言われています。
また、Railsのコントリビュータが作っているだけありかなりRailsの仕組みに似ているので、RailsなどのMVCフレームワークに触れている方には、かなり理解しやすいと思います。
若干、elixirの独特な文法があるため、必要に応じてElixir 基礎文法最速マスターやelixier - 公式を参考にしてください。
※1 earlang(アーラン)は、高可用性で大規模な並列処理が可能なリアルタイムシステムを構築するためにの関数型言語です。例えば、Facebookが買収したWhat's Appという月間アクティブユーザ8億人以上のメッセージアプリ(LINEのようなもの)でも使われています。
しかし、文法が独特で書きづらいというところ不満点があり、それを解決するために、elixerというRuby風のわかりやすいシンタックスで書きやすく、読みやすくした言語が作られました。exlixerはearlang VM上で動くバイトコードに変換されて実行されます。
この記事では、「Phonix環境のセットアップから、静的ページを作成し、表示させる」ことを行います。
目次
動作確認
- Erlang 7.1
- Elixir 1.1.1
- Phoenix 10.0.3
- Hex 0.9.0
- node.js 0.12.7
- npm 2.14.2
- PostgreSQL 9.4.4
1. Phoenix環境のセットアップ
Elixerをインストール
PhoenixはElixerで書かれています。そのため、まずElixerをインストールします。macでHomebrewを使ってインストールする場合はbrewコマンドを使います。
$ brew update $ brew install elixir
他のOSや方法でインストールしたい場合は、Elixerのインストールページを参照してインストールしてください。
Erlangのインストール
ElixirはErlangにコンパイルされて、Erlang VM上で動きます。そのため、Erlangのインストールが必要です。brewコマンドでElixerをインストールした場合、一緒にErlangもインストールされていれますので、インストールされていることを確認します。
$ which erl /usr/local/bin/erl
インストールされていない場合は、Erlangのインストール方法を参照してインストールしてください。
Hex(パッケージマネージャ)のインストール
mix local.hexでHexというErlangのパッケージマネージャをインストールします。
$ mix local.hex
Phoenixのインストール
Phonixのアーカイブをローカルに取得します。$ mix archive.install https://github.com/phoenixframework/phoenix/releases/download/v1.0.3/phoenix_new-1.0.3.ez
node.js (>=0.12.0) のインストール
PhoenixはJavascriptやCSSなどのアセット管理にbranch.ioというビルドツールを使っています。(他に有名なビルドツールとして、gruntやgulpというものがあります。)その
branch.ioがnpm(node用のパッケージマネージャ)を使っているのでnode.jsとnpmが必要になります。nodeとnpmコマンドが使えるか確認し、使えな場合はインストールします。
$ which node /usr/local/bin/node $ which npm /usr/local/bin/npm # nodeやnpmがない場合はインストール $ brew install node
その他のOSや方法の場合は、node.jsのインストールを参照してインストールしてください。
PostgreSQLのインストール
PhonexはデフォルトでPostgresを使う設定になっています。そのため、Postgresが必要になります。brew install postgres
もしMySQLを使いたい場合は、プロジェクトを作成するときに--database mysqlを指定すればよいようです。
これで一通りPhonix環境がセットアップ出来ました。
簡単にまとめると、
- Phonixは、Elixerで書かれていて、ElixerはEarlang VM上で動作するのでEarlangも必要
- Phonixの依存ライブラリのパッケージ管理は、HexというEarlangのパッケージマネージャを使う
- Phonixのアセット管理は、branch.ioというビルドツールを使っている。branch.ioを使うためには、node.jsやnpmが必要
- PhonixのデフォルトのDBは、Postgresを使う。もちろん、MySQLや他のDBも使える
という形になっていて、これらのツールをインストールしました。
2. Phoenixプロジェクトの作成とサーバー起動
Phoenixプロジェクトの作成
mix phonnix.newコマンドで新規のPhoenixプロジェクトを作成します。
$ mix phoenix.new chat_phoenix * creating chat_phoenix/config/config.exs * creating chat_phoenix/config/dev.exs ... Fetch and install dependencies? [Yn] Y * running npm install && node node_modules/brunch/bin/brunch build * running mix deps.get ...
Postgresのセットアップ
PhoenixはデフォルトでPostgresを使います。また、ユーザ名:
postgres、パスワード:postgresのアカウントが必要になります。createuserコマンドでpostgresアカウントをパスワードpostgresで作成します。一応、DB、ロール作成権限をつけておきます。
createuser postgres --createdb --createrole --encrypted --password Password: postgres
既にpostgresアカウントがある場合や別のアカウントを使いたい場合は、config/dev.exsの一番下にユーザ名とパスワードが記載されていますので、こちらを変更してください。
# config/dev.exs # Configure your database config :chat_phoenix, ChatPhoenix.Repo, adapter: Ecto.Adapters.Postgres, username: "postgres", password: "postgres", database: "chat_phoenix_dev", hostname: "localhost", pool_size: 10
データベースの作成
mix ecto.createコマンドでdev環境用のデータベースを作成します。
cd chat_phoenix mix ecto.create => chat_phoenix_devデータベースが作成される # また、MIX_ENV=testを指定することでtest環境用のデータベースが作成できます env MIX_ENV=test mix ecto.create => chat_phoenix_testデータベースが作成される
ectoは、データベース操作やSQLクエリを簡単に記載できるElixerのDSLです。RubyでいうActiveRecordのようなものです。
Phoenixサーバーの起動
mix phoenix.serverでサーバーを起動します。Ctrl + cを2回おすとサーバーを停止できます。
mix phoenix.server
http://localhost:4000にアクセスすれば、次のようが画面が表示されます。
開発で有用なコマンド
これで、PhoenixでWebアプリケーションを動かすことができました。次は静的ページを追加しますが、その前に開発で使える有用なコマンドを記載します。
Phoenixの環境設定でインタラクティブにElixerコマンドを実行するにはiex -S mix phoenix.serverと実行します。iexはinteractive elixerの略です。Ctrl + cを2回押すと停止できます。
$ iex -S mix phoenix.server iex(1)> IO.puts "こんにちは" こんにちは :ok
mix phoenix.routesコマンドで、Phoenixに定義されたすべてのルートを確認できます。
$ mix phoenix.routes page_path GET / ChatPhoenix.PageController :index
3. 静的ページの作成
Phonixで静的ページを追加します。それを通し、ルート、コントローラ、ビュー、テンプレートについて簡単に説明します。Phonixのディレクトリ構成
Phonixのディレクトリ構成は次のようになっています。主に
webにコントローラやモデル、テンプレートなどのアプリケーションのメインとなるファイルを配置します。また、
priv/staticにJSやCSS、イメージなどのアセットファイルを配置します。
chat_phoenix ├── README.md ├── _build ├── brunch-config.js ├── config ├── deps ├── lib ├── mix.exs ├── mix.lock ├── node_modules ├── package.json ├── priv ├── test └── web
また、lib/chat_phoenix/endpoint.exがアプリケーションのエンドポイントになります。
また、lib/chat_phoenix.exがアプリケーションファイルになります。
chat_phoenix ├── lib │ ├── chat_phoenix │ │ ├── endpoint.ex │ │ └── repo.ex │ └── chat_phoenix.ex ...
ルートの追加
web/router.exにルートを記載します。ルートの記載方法は、HTTPメソッド(GET,POSTなど)とパスをコントローラとアクションにひも付けます。
デフォルトで次のように記載されています。
# web/router.ex
defmodule ChatPhoenix.Router do
use ChatPhoenix.Web, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
# api用のスコープ(jsonをaccept)
pipeline :api do
plug :accepts, ["json"]
end
# htmlページ用のスコープ(htmlをaccept)
scope "/", ChatPhoenix do
pipe_through :browser # 上記の :browser の処理を行う
# "GET /"にアクセスすると、PageControllerのindexアクションが呼ばれる
get "/", PageController, :index
end
# Other scopes may use custom stacks.
# scope "/api", ChatPhoenix do
# pipe_through :api
# end
endではget "/hello", HelloController, :indexという新しいルートを追加します。
scope "/", ChatPhoenix do pipe_through :browser # 上記の :browser の処理を行う get "/", PageController, :index # "GET /hello"にアクセスすると、HelloControllerのindexアクションが呼ばれる get "/hello", HelloController, :index end
コントローラの追加
コントローラは、ルートで定義したURLからコントローラとアクションが呼ばれます。そのため、先ほど追加したルートの、
HelloControllerのindexアクションを作成します。ファイルの命名は、web/controllers/<コントローラ名>.exとなります。
# web/controllers/hello_controller.ex
defmodule ChatPhoenix.HelloController do
# Webのcontrollerモジュールを使用できるようにする(おまじないのようなもの)
use ChatPhoenix.Web, :controller
# indexアクション
# conn - リクエスト情報を保持
# params - クエリストリングやフォーム入力などのパラメータ
def index(conn, _params) do
# index.html.eexテンプレートを表示する
render conn, "index.html"
end
end※引数をメソッド内で使っていない場合は、引数名の前に_を追加することで、コンパイラでwarningが発生しなくなります。
ビューを追加
ビューは、コントローラとテンプレートの中間に位置し、プレゼンテーション層としての役割を持ちます。コントローラから渡されたデータを表示用にフォーマットなどしてテンプレートに渡します。
ビューの命名規則は、web/views/<コントローラ名>_view.exとなります。
特にリプレゼンテーションする必要もないので空のビューを作成します。
# web/views/hello_view.ex defmodule ChatPhoenix.HelloView do # Webのviewモジュールを使用できるようにする(おまじないのようなもの) use ChatPhoenix.Web, :view end
テンプレートを追加
テンプレートは、HTMLやJSONを記載します。Phoenixはデフォルトのテンプレートエンジンを
eex(Embedded Elixir)を使っています。そのため、ファイルの拡張子は.eexになります。テンプレートは基本的にはweb/templates/<コントローラ名>/<アクション名>.html.eexに配置します。
<!-- web/templates/hello/index.html.eex --> <div class="jumbotron"> <h2>Hello Phoenix!!</h2> </div>
静的ページの確認
http://localhost:4000/helloにアクセスすると、次のようにページが表示されます。index.html.eexのテンプレートファイルに少ししか書いてませんが、ヘッダやフッターが表示されています。
これは、web/templates/layout/app.html.eexにヘッダーやフッターが記載されているためです。
Phonixはこのapp.html.eexを表示し、このファイル内に、<%= @inner %>があり、ここにindex.html.eexテンプレートの内容が表示されています。
これで、静的ページを表示させることができました。
まとめると、
web/router.exでルートを追加し、HTTPメソッドとURLをコントローラーとアクションにつなげます。web/controllers/<コントローラ名>.exにコントローラを作成し、アクションのメソッドを定義します。web/views/<コントローラ名>_view.exでビューを作成します。web/templates/<コントローラ名>/<アクション名>.html.eexにテンプレートを作成し、htmlを記載します。
という流れでした。