Phoenix に JSON を返却させてみます。特に CRUD 操作などは作りません。
Phoenix のインストールについてはコチラを参照してください。
ルートを追加する
折角なので新しいルートを追加してみましょう。
Phoenix では web/router.ex
というファイルでルーティングを設定します。「/api/:key/:value」で指定した key, value のオブジェクトを返すようにしてみましょう。
...
scope "/", SampleApp do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
end
# 以下のスコープを追加
scope "/api", SampleApp do
pipe_through :api
get "/:key/:value", PageController, :api
end
...
Phoenix のルーティングには パイプライン という概念があり、特定のスコープに対するリクエストに一律の処理を加えることができます。パイプライン自体は プラグ と呼ばれるモジュールの並びで構成されています。Tomcat でいうところのフィルターのようなイメージでしょうか。
デフォルトで生成されるスコープには :browser
というパイプラインが設定されていますが、これはブラウザに表示する HTML を返却することに最適化されたものです。今回のような View に関心がない JSON API の場合は、同じくデフォルトで用意されている :api
というものを使います。
アクションを追加する
次にアクションを追加します。web/controllers/page_controller.ex
に先ほど作成した :api の処理を書きます。
defmodule SampleApp.PageController do
use SampleApp.Web, :controller
def index(conn, _params) do
render conn, "index.html"
end
def api(conn, %{"key" => key, "value" => value}) do
json conn, Map.put(%{}, key, value)
end
end
ルートで :key, :value というパラメータを定義しているので、第2引数にそれらのマッピングを書きます。どうやら各パラメータはアトムにはならないようで、キーワード構文は使えないみたいです。
JSON を返却する場合は json/2
という関数を呼び出します。第1引数にはコネクション情報、第2引数には JSON にしたいオブジェクトを渡します。
ちなみにこの json
やルーティングで書いた get
といったものはマクロで、内部的に関数呼び出しに展開されているようです。Phoenix ではこのようなマクロの活用が散見されます。
マップの作成は %{"foo" => "bar"}
や %{foo: "bar"}
のように書くのですが、今回のようにキーを文字列型の変数にしたい場合の方法がイマイチ分からなかったので、Map モジュールの put/3
を使って作成しています。
リクエストしてみる
ブラウザで適当に(ex: /api/hello/world)リクエストを投げてみると、ちゃんと意図通りの返却になっていることがわかります。
{
"hello": "world"
}
ちなみに、パラメータが足りていないと「no route found」としてエラー画面に飛びます。