上篇文章帶大家基本了解了一下開始一個 Vapor 項目的流程,本篇緊接著來說說在所有 Web 框架中都最關鍵的 “路由”,因為 “路由” 模塊在 Web 項目中擔任很重要的角色,所以很多語言的 Web 框架都把 “路由” 抽離到框架層,從而減少開發者的工作量,一個設計得易用強大的 “路由” 系統也會給相應給框架增添不少色彩。
Web 開發中的路由這個概念簡單來說就是 URL 路徑到具體處理函數之間的映射,只有設定好了路由,訪問者才能在瀏覽器根據相關 URL 規則進行頁面跳轉和訪問,Vapor 對路由做了很多實用性設計,包括路由的構建、路由組、類型安全的路由參數、路由集合等等,希望看完本篇文章你能用 Vapor 寫出一些簡單的路由,我們先來看看 Vapor 最簡單的路由注冊。
注冊路由之前我們需要知道 Droplet
這個類,每個程序都應該有一個它的實例,控制著整個程序的生命周期,之后我們會通過 droplet 來注冊路由,添加 PRovider,添加中間件 (middleware) 等等。 droplet 的初始化很簡單,一個空程序看起來就像這樣:
注冊一個最基本的路由通過對全局 Droplet
對象調用一個方法,指定路徑和一個閉包來接收操作處理。
我們通過調用 get()
方法來注冊了一個路徑為 /welcome
的路由,并返回了 “Hello” 這個字符串到瀏覽器,當然我們除了 get
還可以其他的標準 HTTP 方法,比如 post
、 put
、 patch
、 delete
、options
。
另外我們還可以使用 add()
方法來注冊路由,以接收第一個參數 Method
作為 HTTP 方法來動態注冊路由,Method
是一個枚舉,包含了上述所列的 HTTP 標準方法,代碼看起來是這樣:
可能你會想明明上面已經提供了對應的方法來注冊路由,為什么還要多一個 add()
方法來注冊路由?因為這個方法可以動態注冊,并且支持一些其他不常見的方法(比如 trace
)。
另外有一種關于多級路徑的寫法,直接使用參數分割,而不是在一個 String 參數中用 /
分開,官方推薦是這種寫法,因為可以更容易寫出類型安全的路由參數。
如果想在 URL 路由中使用通配符怎么辦?
app.get("anything", "*") { request in return "Matches anything after /anything"}像這個例子因為用了 *
尾隨參數,可以匹配到如下所有路徑:
每個路由的閉包都會有一個 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
也已經默認實現。
每個路由的閉包中可以返回三種類型的內容,Response
、ResponseRepresentable
、throw
,你可以你可以返回自己所需的 HTTP 狀態碼、URL 重定向、JSON等,基本涵蓋日常所需的請求返回。
Response
是 Vapor 中 HTTP 模塊中定義的基于 Message 的類,有很多構造方法方便我們自定義 response 返回:
ResponseRepresentable
是一個協議,任何遵循這個協議的對象均可在路由中返回,就像之前例子中我們直接返回了字符串,就是因為 Vapor 默認給 String
實現了 ResponseRepresentable
協議,讓我們可以方便的在閉包中直接返回字符串,類似的還有 JSON
、Model
對象。
另外一大特性就是可以直接在路由中拋出異常,我們可以 throw 任何遵從 Swift.Error
協議的對象,當然 Vapor 已經為我們封裝好了幾個常用的 Error 來方便我們拋出異常。
當我們請求這個地址的時候一般會看到一個 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
對象來收納路由。
文章到此關于 Vapor 路由基本的內容也差不多都介紹完畢了,當然這里講的可能并不全面,示例代碼基本來自于官方文檔(感謝
新聞熱點
疑難解答