Phoenix本を買ったのでまとめつつ読んでいく。
Phoenixは、生産性が高く、処理速度も圧倒的に速いフレームワークである。また、コードが美しい。
単純な関数
PhoenixはElixirで動く。Elixirには、次のような関数がある。
def inc(x), do: x + 1
def dec(x), do: x - 1
次のようにチェインさせて呼び出すことができる。
2 |> inc |> inc |> dec
|>
(パイプ演算子)は左辺の値を第一引数として右辺の関数に渡す。このような構成をパイプ、またはパイプラインと呼ぶ。このとき呼び出される各関数をセグメント、またはパイプセグメントと呼ぶ。
パイプラインもまた関数なので、パイプラインのパイプラインを作ることもできる。Phoenixのプログラムはパイプを使うと次のように表現できる。
connection |> phoenix
Phoenixでは、connectionがユーザーのリクエストに関する全ての情報を含んでいる構造体である。そしてPhoenixの各層がconnectionに対して変化を加えていく。Phoenixが終了するときにはconnectionはresponseを保持している。
Phoenixの層
Phoenixを簡単化して、あるHTTPのリクエストをどのように処理するか見てみよう。
connection
|> endpoint
|> router
|> pipelines
|> controller
各リクエストはまずendpointへ届く。そして次にrouterへと行き、適切なcontrollerに導く。controllerの前に、いくつかのpipelinesを通過する。いくつかはブラウザのリクエストに対するもので、いくつかはJSONのリクエストによるパイプラインである。
コントローラの内部での処理
PhoenixはModel-View-Controller(MVC)パターンで実装される。モデルはデータへアクセスし、ビューはデータを表示する。そしてコントローラはその中間に位置していて、次のようなパイプラインになっている。
connection
|> controller
|> common_services
|> action
controllerでcommon_servicesが呼び出されている。Phoenixにおいてこれらのcommon_servicesはPlugによって定義されている。いったん、PlugはWebアプリやライブラリを簡単に構築するためのものだと思ってもらって良い。
actionsには他のWebサイトへのアクセスから、ユーザーの認証まで、様々な種類のものがある。多くの場合はactionsはデータベースにアクセスし、ビューを描画する。例えばユーザーを表示するactionは次のようなものになる。
connection
|> find_user
|> view
|> template
最初のプロジェクトの作成
Phoenixのインストールはここでは扱わないが、インストールを終えたら、Hello Worldに相当するプロジェクトを作ってみよう。mixコマンドを使う。
mix phoenix.new hello
cd hello
mix ecto.create
mix phoenix.server
localhost:4000にアクセスするとページが表示される。
機能の追加
特定のURLを叩いたらある文字列が表示されるように機能を追加していこう。まずは特定のURLに対してリクエストが届いたら、望ましい処理が行えるようにマッピングをしたい。これには、web/router.ex
を編集する。
scope "/", Hello do
pipe_through :browser
get "/hello", HelloController, :world
get "/", PageController, :index
end
追加した行によって、"/hello"から始まるURLへのリクエストがHelloControllerの:world関数によって処理されるようにマッピングされる。
ではそのHelloControllerを作成しよう。
defmodule Hello.HelloController do
use Hello.Web, :controller
def world(conn, _params) do
render conn, "world.html"
end
end
use Hello.Web, :controller
によってPhoenixのController APIが使えるようになる。ここではviewを描画しようとしている。続いてviewを作成しよう。
defmodule Hello.HelloView do
use Hello.Web, :view
end
同じくworld.htmlテンプレートが必要だ。
<h1>From template: Hello world!</h1>
これでlocalhost:4000/helloにアクセスした際にHello worldが表示されるようになった。暗黙的にweb/views/layout_view.ex
のビューとweb/templates/layout/app.html.eex
が使われていることに注意してほしい。
(#2に続く)