上篇文章帶你們基本瞭解了一下開始一個 Vapor 項目的流程,本篇緊接着來講說在全部 Web 框架中都最關鍵的 「路由」,由於 「路由」 模塊在 Web 項目中擔任很重要的角色,因此不少語言的 Web 框架都把 「路由」 抽離到框架層,從而減小開發者的工做量,一個設計得易用強大的 「路由」 系統也會給相應給框架增添很多色彩。html
Web 開發中的路由這個概念簡單來講就是 URL 路徑到具體處理函數之間的映射,只有設定好了路由,訪問者才能在瀏覽器根據相關 URL 規則進行頁面跳轉和訪問,Vapor 對路由作了不少實用性設計,包括路由的構建、路由組、類型安全的路由參數、路由集合等等,但願看完本篇文章你能用 Vapor 寫出一些簡單的路由,咱們先來看看 Vapor 最簡單的路由註冊。git
註冊路由以前咱們須要知道 Droplet
這個類,每一個程序都應該有一個它的實例,控制着整個程序的生命週期,以後咱們會經過 droplet 來註冊路由,添加 provider,添加中間件 (middleware) 等等。 droplet 的初始化很簡單,一個空程序看起來就像這樣:github
import Vapor let drop = Droplet() // your magic here drop.run()
註冊一個最基本的路由經過對全局 Droplet
對象調用一個方法,指定路徑和一個閉包來接收操做處理。json
drop.get("welcome") { request in return "Hello" }
咱們經過調用 get()
方法來註冊了一個路徑爲 /welcome
的路由,並返回了 "Hello" 這個字符串到瀏覽器,固然咱們除了 get
還能夠其餘的標準 HTTP 方法,好比 post
、 put
、 patch
、 delete
、options
。swift
另外咱們還可使用 add()
方法來註冊路由,以接收第一個參數 Method
做爲 HTTP 方法來動態註冊路由,Method
是一個枚舉,包含了上述所列的 HTTP 標準方法,代碼看起來是這樣:segmentfault
drop.add(.trace, "welcome") { request in return "Hello" }
可能你會想明明上面已經提供了對應的方法來註冊路由,爲何還要多一個 add()
方法來註冊路由?由於這個方法能夠動態註冊,而且支持一些其餘不常見的方法(好比 trace
)。瀏覽器
另外有一種關於多級路徑的寫法,直接使用參數分割,而不是在一個 String 參數中用 /
分開,官方推薦是這種寫法,由於能夠更容易寫出類型安全的路由參數。安全
drop.get("foo", "bar", "baz") { request in return "You requested /foo/bar/baz" }
若是想在 URL 路由中使用通配符怎麼辦?閉包
app.get("anything", "*") { request in return "Matches anything after /anything" }
像這個例子由於用了 *
尾隨參數,能夠匹配到以下全部路徑:app
/anything
/anything/foo
/anything/foo/bar
/anything/foo/bar/baz
每一個路由的閉包都會有一個 Request
參數,用來得到每個訪問請求的相關內容,好比 URL 參數、HTTP Header、HTTP Body 等等,並且 Vapor 都已經爲你封裝好了很方便的接口來獲取這些內容,甚至直接解析 JSON。
詳細使用能夠參考官方文檔 Request 一節。
Vapor 提倡使用類型安全的路由參數來接收數據,咱們能夠在路由方法中使用 Swift 類型來指定參數類型,Vapor 會在內部解析並將參數返回給閉包以供使用,很是方便。
drop.get("users", Int.self) { request, userId in return "You requested User #\(userId)" }
Swift 中到處有協議,路由參數也是如此,咱們所見例子中的 Int
其實就是 Vapor 給實現了 StringInitializable
協議,固然 String
也已經默認實現。
public protocol StringInitializable { init?(from string: String) throws }
每一個路由的閉包中能夠返回三種類型的內容,Response
、ResponseRepresentable
、throw
,你能夠你能夠返回本身所需的 HTTP 狀態碼、URL 重定向、JSON等,基本涵蓋平常所需的請求返回。
Response
是 Vapor 中 HTTP 模塊中定義的基於 Message 的類,有不少構造方法方便咱們自定義 response 返回:
// 重定向 Response(redirect: "http://vapor.codes") // JSON Response(status: .ok, json: JSON(["hello":"world"])) // String Response(body: "hello")
ResponseRepresentable
是一個協議,任何遵循這個協議的對象都可在路由中返回,就像以前例子中咱們直接返回了字符串,就是由於 Vapor 默認給 String
實現了 ResponseRepresentable
協議,讓咱們能夠方便的在閉包中直接返回字符串,相似的還有 JSON
、Model
對象。
另一大特性就是能夠直接在路由中拋出異常,咱們能夠 throw 任何聽從 Swift.Error
協議的對象,固然 Vapor 已經爲咱們封裝好了幾個經常使用的 Error 來方便咱們拋出異常。
drop.get("404") { request in throw Abort.notFound }
當咱們請求這個地址的時候通常會看到一個 Vapor 默認提供的錯誤頁面,還挺漂亮的,若是不想用 Vapor 提供的默認錯誤頁面,咱們能夠從 drop.middleware
中移除 AbortMiddleware
並添加本身的實現便可。
Abort 枚舉在 Vapor 中定義以下:
public enum Abort: Swift.Error { case badRequest case notFound case serverError case custom(status: Status, message: String) }
Status 枚舉了幾十個咱們可能用到的 HTTP 狀態碼,如 200(.ok
)、 301(.movedPermanently
)、403(.forbidden
) ...
Vapor 提供了路由組的概念,一般用來集中組織一組相同前綴,添加中間件,限制主機名,或者集中管理的路由,路由組有兩個類型:Group
和 Grouped
。
Group 經過一個閉包來收納旗下全部的路由,讓它們有統一的路徑前綴,示例以下:
drop.group("v1") { v1 in v1.get("users") { request in // get the users } }
Grouped 原理相似,只是形式上有所變化,經過 drop.grouped()
方法返回一個 RouteGroup
對象來收納路由。
let v1 = drop.grouped("v1") v1.get("users") { request in // get the users }
文章到此關於 Vapor 路由基本的內容也差很少都介紹完畢了,固然這裏講的可能並不全面,示例代碼基原本自於官方文檔,下一篇準備說說 Vapor 的模版引擎 Leaf。
以前開的坑在寫一個博客程序 NSPress,若是你們有興趣歡迎討論。