LoginSignup
3
3

More than 5 years have passed since last update.

Phoenixガイドラインを読んでみた(4) - Plug -

Last updated at Posted at 2016-04-22

はじめに

前回は、Routingについてまとめてみました。
今回は、公式ドキュメントのPlugです。
なお、次回は、ガイドラインのControllerです。

消火栓

Plugは、HTTPレイヤー間のさまざまな局面で接続を行うことができる仕様です。
おおまかに関数型Plugとモジュール型Plugの二つの書き方ができます。

関数型Plug

Plugとして動作するためには、接続データ(%Plug.Conn{})とパラメータ引数を受け取り、接続データを返す必要があります。
例えば、以下のようなControllerを作成します(関連箇所のみ抜粋)。

defmodule HelloPhoenix.MessegeController do
  use HelloPhoenix.Web, :controller

  plug :put_headers, %{content_encoding: "gzip", cache_control: "max-age=3600"}

  def show(conn, _params) do
    render conn, "show.html"
  end

  defp put_headers(conn, key_values) do
    # key_valuesがEnum, accumlatorがconn
    # Enum.reduce/3はaccumlator(conn)を返す
    Enum.reduce key_values, conn, fn {k, v}, conn ->
      Plug.Conn.put_resp_header(conn, k, v)
    end
  end
end

これは、"show.html"を表示する前に、"content_encoding"と"cache_control"の二つのヘッダを表示します。
なお、このようにControllerに直接Pipelineを書くことができますが、記述することができるPipelineは一つだけです。

モジュール型Plug

モジュール型Plugを作成する場合、init/1とcall/2の二つの関数を実装するだけです。
init/1は、call/2へのパラメータを生成します。また、call/2は関数型Plugと同じく接続データとパラメータを引数にします。

例えば、以下のような実装を行います(関連する部分だけを抜粋)。

defmodule HelloPhoenix.Plugs.Locale do
  import Plug.Conn

  @locales ["en", "fr", "de"]

  def init(default), do: default

  def call(%Plug.Conn{params: %{"locale" => loc}} = conn, _default) when loc in @locales do
    assign(conn, :locale, loc)
  end
  def call(conn, default), do: assign(conn, :locale, default)
end

defmodule HelloPhoenix.Router do
  use HelloPhoenix.Web, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug HelloPhoenix.Plugs.Locale, "en"
  end
...

Pipeline :browserに、モジュール型Plug HelloPhoenix.Plugs.Localeを追加しています。
このとき、引数"en"が、init/1関数の引数として与えられます。
Plug(HelloPhoenix.Plugs.Locale)が実行されるとき、HelloPhoenix.Plugs.Localeのcallが呼び出されます。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3