Controllers可以幫你將相關(guān)功能整合到一起,或者創(chuàng)建一些依賴性的資源。
Basic
下面是一個基本的Controller
:
final class HelloController {
func sayHello(_ req: Request) throws -> ResponseRepresentable {
guard let name = req.data["name"] else {
throw Abort.badRequest
}
return "Hello, \(name)"
}
}
一個簡單的控制器類不需要遵守任何協(xié)議,你可以自由的設(shè)計、實現(xiàn)你想要的功能棵癣。
Registering
實現(xiàn)注冊唯一要做的事情就是為controller中的每個方法進(jìn)行簽名(看看上面sayHello
方法的結(jié)構(gòu))。為了將controller中的方法注冊到路由中去夺衍,需要方法實現(xiàn)類似于(Request) throws -> ResponseRepresentable
的結(jié)構(gòu)狈谊。 Request
和ResponseRepresentable
的使用需要引入HTTP
模塊。
let hc = HelloController()
drop.get("hello", handler: hc.sayHello)
由于sayHello
方法的簽名與drop.get
方法的閉包簽名相匹配,所以我們可以直接傳遞河劝。
Type Safe(類型安全)
你也可以使用具有類型安全路由的控制器方法:
final class HelloController {
...
func sayHelloAlternate(_ req: Request, _ name: String) -> ResponseRepresentable {
return "Hello, \(name)"
}
}
將sayHelloAlternate
方法添加到HelloController
當(dāng)中壁榕,它可以接收第二個參數(shù)name: String
。
let hc = HelloController()
drop.get("hello", String.self, handler: hc.sayHelloAlternate)
類型安全的drop.get
接收(Request, String) throws -> ResponseRepresentable
簽名之后丧裁,我們的方法就可以用作這個路由的閉包护桦。
Resources
遵守ResourceRepresentable
的Controllers可以很輕松的作為RESTful資源注冊到路由當(dāng)中,下面用UserController
舉例:
final class UserController {
func index(_ request: Request) throws -> ResponseRepresentable {
return try User.all().makeNode().converted(to: JSON.self)
}
func show(_ request: Request, _ user: User) -> ResponseRepresentable {
return user
}
}
上面的UserController
是一個很基本的controller煎娇,包含index
和show
兩個路由二庵,index
路由返回的是所有user
列表的json數(shù)據(jù),show
路由返回的是一個具體user
的json數(shù)據(jù)缓呛。
我們注冊這個controller的時候這樣寫:
let users = UserController()
drop.get("users", handler: users.index)
drop.get("users", User.self, handler: users.show)
但是ResourceRepresentable
協(xié)議使得這個標(biāo)準(zhǔn)的RESTful結(jié)構(gòu)變得非常容易:
extension UserController: ResourceRepresentable {
func makeResource() -> Resource<User> {
return Resource(
index: index,
show: show
)
}
}
UserController
遵守ResourceRepresentable
協(xié)議要求將
show
和index
方法的簽名與Resource<User>
期望的格式相匹配催享。
看一下Resource類的實現(xiàn):
final class Resource<Model: StringInitializable> {
typealias Multiple = (Request) throws -> ResponseRepresentable
typealias Item = (Request, Model) throws -> ResponseRepresentable
var index: Multiple?
var store: Multiple?
var show: Item?
var replace: Item?
var modify: Item?
var destroy: Item?
var clear: Multiple?
var aboutItem: Item?
var aboutMultiple: Multiple?
...
}
現(xiàn)在UserController
遵守了ResourceRepresentable
協(xié)議,注冊路由就變的簡單了:
let users = UserController()
drop.resource("users", users)
drop.resource
只會注冊通過調(diào)用makeResource()
方法提供的路由哟绊。在這種情況下因妙,只會啟用index
和show
這兩個路由。
Note:
drop.resource
還為OPTIONS requests
添加了有用的默認(rèn)值票髓。這些可以被重寫攀涵。
Folder
Controllers可以放在應(yīng)用的任何目錄下,但是一般放在Controllers/
目錄中洽沟。
Modules
如果你的項目比較龐大以故,你可能需要在單獨(dú)的模塊中創(chuàng)建Controllers,這樣可以允許你對你的controllers進(jìn)行單元測試裆操。更多關(guān)于模塊創(chuàng)建的信息請參考文檔Swift Package Manager