Programming Phoenix勉強その2
Programming Phoenix勉強その2
その2です。 その1の続きです。
デフォルトのディレクトリ構成について
configディレクトリPhoenixの設定ファイル置き場.名前のまま.
prod.secret.exsは秘密情報が入っているファイルなので,VCSからは外すこと.config.exsのendpointはWebサーバーとアプリケーションの接続の境界部分.
libディレクトリSupervision treeと,長く起動するプロセスが置かれる.(?,あってるか微妙)
DBとのコネクションプールとかのような長く使われるものが置かれるっぽい.
testディレクトリ名前の通りテストが置かれる.
webディレクトリWebアプリに必要な
model,view,template,controllerが置かれる.
Plugについて
Plug ライブラリは接続の統一化のために使われる. Plug のリポジトリ Plugリポジトリ には以下のように書いてある.
・ A specification for composable modules between web applications ・ Connection adapters for different web servers in the Erlang VM
なので,各機能のモジュールの仕様の記述と,Erlang VMと各Webサーバーとの接続をやってくれるみたいです. (あまり理解してない感が) 実際にPhoenixが作ってくれる物を見てみます. config/endpoint.exs を見てみます.
defmodule Hello.Endpoint do
use Phoenix.Endpoint, otp_app: :hello
socket "/socket", Hello.UserSocket
# Serve at "/" the static files from "priv/static" directory.
#
# You should set gzip to true if you are running phoenix.digest
# when deploying your static files in production.
plug Plug.Static,
at: "/", from: :hello, gzip: false,
only: ~w(css fonts images js favicon.ico robots.txt)
# Code reloading can be explicitly enabled under the
# :code_reloader configuration of your endpoint.
if code_reloading? do
socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
plug Phoenix.LiveReloader
plug Phoenix.CodeReloader
end
plug Plug.RequestId
plug Plug.Logger
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Poison
plug Plug.MethodOverride
plug Plug.Head
# The session will be stored in the cookie and signed,
# this means its contents can be read but not tampered with.
# Set :encryption_salt if you would also like to encrypt it.
plug Plug.Session,
store: :cookie,
key: "_hello_key",
signing_salt: "zzWE+Yw+"
plug Hello.Router
end
とりあえず plug ってのがいっぱい出てきています. なんとなく見てると, plug Plug.Static で静的ファイルについての設定っぽいものが書いてあったり, plug Plug.Logger とか, plug Plug.Parsers とかあったりして,Webアプリに必要な設定が書いてあるっぽいなと言う感覚です. ココらへんの一連の plug は関数のパイプラインとして処理されるようです.
connection
|> Plug.Static.call
|> Plug.RequestId.call
|> Plug.Logger.call
|> Plug.Parsers.call
|> Plug.MethodOverride.call
|> Plug.Head.call
|> Plug.Session.call
|> Hello.Router.call
ソースに書いた順になってるっぽいです.Servletの設定順ミスってハマった思い出が… ちなみに endpoint 自体も plug で,アプリケーション自体は endpoint で始まり controller で終わる一連のパイプラインらしい.
Routerについて
web/router.ex のソースを見ると,2つのパイプラインがあることがわかる.
defmodule Hello.Router do
use Hello.Web, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", Hello do
pipe_through :browser # Use the default browser stack
get "/hello/:name", HelloController, :world
get "/", PageController, :index
end
# Other scopes may use custom stacks.
# scope "/api", Hello do
# pipe_through :api
# end
end
browserパイプラインHTMLのみを受け付ける.
セッション管理とか,フラッシュメッセージとか,セキュリティ対策とかを提供してくれるらしい.
apiパイプライン基本的なJSON API用のパイプライン.JSONのみ受け付ける.
XMLにしたいときとかはここ一箇所変更すれば全部変更される.
pipe_through でどのパイプラインを使うか書く. 処理の流れとしては接続を取得→パイプラインを呼び出し→コントローラーを呼び出し. 呼び出し順を纏めると以下になる.
connection
|> endpoint
|> router
|> pipeline
|> controller
まとめ
今回は,内部的な処理の流れとかおまじない的な部分が何をしてるかの勉強だった感じです. 英語がヘタレ過ぎて自分が理解している意味とあってるか若干の不安が...