須要一些 Elixir
的基礎. html
對於沒有Erlang
背景知識的同窗, 有比較陡峭的學習曲線. 可是Elixir語言提供了一個庫: Plug, 用它咱們可以開發基於Erlang VM的Web應用.git
本文采用 Cowboy 做爲Web服務器, 來構造一個超級簡單的Web應用. 它惟一的功能就是在瀏覽器上顯示一個純文本: "Hello World!". Plug
不是一個Web框架, 它不是用來替代 Phoenix
或 Sugar
的, 相反,這兩個框架都使用了Plug來與底層的HTTP服務器(Cowboy)交互.github
經過命令mix new --sup plug_sample
建立一個項目.web
在mix.exs
文件中添加依賴json
defp deps do [{:cowboy, "~> 1.0.0"}, {:plug, "~> 0.12"}] end
安裝依賴api
mix deps.get
把:cowboy
和:plug
添加到application
函數瀏覽器
def application do [applications: [:logger, :cowboy, :plug], mod: {PlugSample, []}] end
Plug
在PlugSample.Worker
啓動Plug
, PlugSample.Worker
由PlugSample.start/2
啓動服務器
defmodule PlugSample.Worker do def start_link do Plug.Adapters.Cowboy.http PlugSample.MyPlug, [] end end
Plug.Router
建立路由模塊 lib/elixir_plug_examples/router.ex
session
defmodule ElixirPlugExamples.Router do use Plug.Router if Mix.env == :dev do use Plug.Debugger end plug :match plug :dispatch # Root path get "/" do send_resp(conn, 200, "This entire website runs on Elixir plugs!") end end
路由模塊建立完成後, 就能夠經過iex -S mix
來啓動這個簡單的Web應用程序了. 訪問 http://localhost:4000/.app
使用 curl -v http://localhost:4000
鏈接到服務器, -v
選項讓咱們能夠看到響應頭信息.
響應頭以下:
> GET / HTTP/1.1 > Host: localhost:4000 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < server: Cowboy < date: Tue, 12 Apr 2016 08:25:38 GMT < content-length: 11 < cache-control: max-age=0, private, must-revalidate < content-type: text/plain; charset=utf-8 < Hello world
本文網站的示例代碼
https://github.com/developerworks/plug_sample
Plug
是一段代碼片斷, 它通常插入到請求處理鏈條中的一個特定位置.
多個Plug
構成一個完整的處理鏈條
請求首先被轉換成%Plug.Conn{}
結構, 並傳遞個鏈條中的第一個Plug
, 第一個Plug
處理(修改,增長,刪除)完成後, 傳遞給後續的Plug
Plug
函數的Plug
函數Plug
是一個接受%Plug.Conn
和一個選項列表做爲參數, 並返回一個%Plug.Conn
的函數
, 例如:
def my_plug(conn, opts) do conn end
模塊的Plug
模塊Plug
是一個實現了init/1
, 和run/2
函數的模塊:
module MyPlug do def init(opts) do opts end def call(conn, opts) do conn end end
模塊Plug
有一個特色是: init/1
在編譯時運行, run/2
在運行時運行. 由init/1
返回的值會被傳遞給run/2
. 所以儘可能吧繁重的工做安排到init/1
去執行對Plug的性能有很是大的提高.
在Phoenix中, 可使用管道pipeline
把多個Plug
組合到一塊兒.
好比:
針對瀏覽器
的管道(輸出HTML
):
pipeline :browser do plug :accepts, ["html"] plug :fetch_session plug :fetch_flash plug :protect_from_forgery plug :put_secure_browser_headers end
針對API接口
的管道(輸出JSON
)
pipeline :api do plug :accepts, ["json"] end
Plug
提供了一個Plug.Test
模塊簡化Plug
的測試, 下面是一個例子
defmodule MyPlugTest do use ExUnit.Case, async: true use Plug.Test @opts AppRouter.init([]) test "returns hello world" do # Create a test connection conn = conn(:get, "/hello") # Invoke the plug conn = AppRouter.call(conn, @opts) # Assert the response and status assert conn.state == :sent assert conn.status == 200 assert conn.resp_body == "world" end end
Plugs
Plug Types | Description |
---|---|
Plug.CSRFProtection |
添加跨站點請求保護, 若是要使用Plug.Session ,這個是必須的; |
Plug.Head |
把HEAD 請求轉換爲GET 請求; |
Plug.Logger |
記錄請求; |
Plug.MethodOverride |
重寫指定在請求頭中指定的方法; |
Plug.Parsers |
根據Content-Type 負責解析請求體; |
Plug.RequestId |
設置一個請求ID, 用在日誌中; |
Plug.Session |
處理會話管理和存儲; |
Plug.SSL |
強制請求經過SSL; |
Plug.Static |
處理靜態文件; |
Plug.Debugger |
調試頁面 |
Plug.ErrorHandler |
容許開發者定製錯誤頁面, 而不是發送一個空頁面. |