[翻譯][erlang]cowboy路由模塊使用

Cowboy是基於Erlang實現的一個輕量級、快速、模塊化的http web服務器。git

本文官方原文:http://ninenines.eu/docs/en/cowboy/1.0/guide/routing/github

默認狀況下,Cowboy不會作什麼事情。
爲了使Cowboy可用,須要映射URL和處理請求的Erlang模型(Module),這個過程,咱們稱之爲路由(routing)。
當Cowboy接收到一個請求,經過路由,Cowboy就會嘗試去匹配到相應請求的主機和資源路徑。若是匹配成功,那麼相關的Erlang代碼就會被執行。
每一個主機會給出相應的路由規則。Cowboy首先會匹配主機,而後嘗試尋找匹配的路徑。
在使用Cowboy以前須要先編譯路由。web

1. Structure(結構)

路由通常定義成如下結構服務器

Routes = [Host1, Host2, ... HostN].

每一個主機包含匹配規則(HostMatch)、限制規則(非必須)(Constraints)和一個由路徑組成的路由列表(PathsList)。dom

Host1 = {HostMatch, PathsList}.
Host2 = {HostMatch, Constraints, PathsList}.

由路徑組成的路由列表與主機列表相似。ide

PathsList = [Path1, Path2, ... PathN].

而路徑(path)包含匹配路徑規則、限制規則(非必須)、處理邏輯的module和會被初始化的選項參數。模塊化

Path1 = {PathMatch, Handler, Opts}.
Path2 = {PathMatch, Constraints, Handler, Opts}.

下面內容爲匹配語法和限制選項。函數

2. Match syntax(匹配語法)

匹配語法用來關聯主機名字和相應的handler路徑。
主機的匹配語法和路徑的匹配語法相似,只有輕微的區別。譬如,他們分隔符是不同的。並且主機是從最後開始匹配的,而路徑是否是。
(其實說了老半天,這不就是一個普通的URL嘛。URL的前半部分爲主機IP或域名,這裏稱之爲HOST,即主機。然後半部分爲路徑)
除了特殊狀況,最簡單的匹配就是隻有主機或者只有路徑的匹配。他的值能夠爲string() 或binary() 類型。ui

PathMatch1 = "/".
PathMatch2 = "/path/to/resource".

HostMatch1 = "cowboy.example.org".

正如你所見,全部的路徑都是由斜槓開始的。注意,下面兩條路徑對於路由而言是同樣的。atom

PathMatch2 = "/path/to/resource".
PathMatch3 = "/path/to/resource/".

而對於主機名,最後有點和沒有點對於路由來講也是同樣的。一樣,在前面多一個點和少一個點也是同樣的。

HostMatch1 = "cowboy.example.org".
HostMatch2 = "cowboy.example.org.".
HostMatch3 = ".cowboy.example.org".

所以可以提取主機和路徑的數據段而且存儲在Req 對象供後面使用。咱們稱之爲值綁定。
綁定語法很是簡單。由冒號字符(:)開頭,一直到數據段的結尾的這個數據段是咱們的綁定名稱,會被保存。

PathMatch = "/hats/:name/prices".
HostMatch = ":subdomain.example.org".

若是這兩個最終匹配,那麼就會有兩個綁定定義,分佈是:subdomain 和:name ,每一個包含被定義的數據段。例如,這個URL地址 http://test.example.org/hats/wild_cowboy_legendary/prices 會將 test綁定到subdomain ,並將wild_cowboy_legendary 綁定到 name 。他們經過cowboy_req:binding/{2,3} 函數檢索出來的。綁定名字必須是原子(atom)類型。

還有一種特殊的綁定名字,它模仿erlang的下劃線變量。任意內容都能與下劃線(_)相匹配,可是數據會被丟棄。最有用的場景就是去匹配多個域名。

HostMatch = "ninenines.:_".

相似地,也能夠添加可選內容。中括號內的內容都是可選的。

PathMatch = "/hats/[page/:number]".
HostMatch = "[www.]ninenines.eu".

而且可選內容能夠內嵌

PathMatch = "/hats/[page/[:number]]".

還可使用[...] 來獲取主機名或路徑剩餘的部分。匹配主機的時候,須要放在最前面;匹配路徑的時候是放在最後面。分別使用cowboy_req:host_info/1 和 cowboy_req:path_info/1 函數能夠找到他們。

PathMatch = "/hats/[...]".
HostMatch = "[...]ninenines.eu".

若是一個綁定變量出現了兩次,那麼只有這兩個位置的值相同的時候纔會匹配成功。

PathMatch = "/hats/:name/:name".

在可選變量裏面也是同樣的,在下面這個例子中,若是可選變量有值,必須兩個綁定變量的值都同樣纔可匹配到。

PathMatch = "/hats/:name/[:name]".

若是一個綁定變量出如今主機名和路徑當中,他們須要是相同的才能匹配。

PathMatch = "/:user/[...]".
HostMatch = ":user.github.com".

固然也有兩種特殊狀況,第一種使用下劃線變量(_)能夠匹配任意的主機名和路徑。

PathMatch = '_'.
HostMatch = '_'.

第二種,使用通配符星號(*)來匹配。

HostMatch = "*".

3. Constraints(約束)

關於這段沒看懂,下面是英文原文:

After the matching has completed, the resulting bindings can be tested against a set of constraints. Constraints are only tested when the binding is defined. They run in the order you defined them. The match will succeed only if they all succeed.

They are always given as a two or three elements tuple, where the first element is the name of the binding, the second element is the constraint's name, and the optional third element is the constraint's arguments.

The following constraints are currently defined:

  • {Name, int}
  • {Name, function, fun ((Value) -> true | {true, NewValue} | false)}

The int constraint will check if the binding is a binary string representing an integer, and if it is, will convert the value to integer.

The function constraint will pass the binding value to a user specified function that receives the binary value as its only argument and must return whether it fulfills the constraint, optionally modifying the value. The value thus returned can be of any type.

Note that constraint functions SHOULD be pure and MUST NOT crash.

4. Compilation(編譯/收集)

在傳遞給Cowboy以前,定義的結構首先要先編譯。才能是Cowboy有效查找到正確的handler,並執行,而沒必要重複地解析路由。
編譯經過調用cow_router:compile/1 函數進行。

Dispatch = cowboy_router:compile([
    %% {HostMatch, list({PathMatch, Handler, Opts})}
    {'_', [{'_', my_handler, []}]}
]),
%% Name, NbAcceptors, TransOpts, ProtoOpts
cowboy:start_http(my_http_listener, 100,
    [{port, 8080}],
    [{env, [{dispatch, Dispatch}]}]
).

注意,若是結構不正確,函數會返回{error, badarg}。

5. Live update(熱更新)

使用cowboy:set_env/3 函數能夠更新當前的路由列表。這會應用到全部的監聽器中。

cowboy:set_env(my_http_listener, dispatch,
    cowboy_router:compile(Dispatch)).

注意,設置以前仍是須要編譯的哦。

相關文章
相關標籤/搜索