Vapor 2.0 - 控制器(Controllers)

前往 Vapor 2.0 - 文檔目錄

控制器幫助您將相關(guān)的功能組織到一個地方冶忱。它們還可以用于創(chuàng)建RESTful資源。

基本(Basic)

一個基本的控制器看起來像下面這樣:

import Vapor
import HTTP

final class HelloController {
    func sayHello(_ req: Request) throws -> ResponseRepresentable {
        guard let name = req.data["name"]?.string else { 
            throw Abort(.badRequest)
        }

        return "Hello, \(name)"
    }
}

簡單的控制器不需要遵守任何協(xié)議。你可以自由地設(shè)計它們,只要你認(rèn)為合適。

注冊(Registering)

唯一需要的結(jié)構(gòu)是控制器中每個方法的簽名盾鳞。為了將這個方法注冊到路由器中,它必須有一個簽名瞻离,(Request) throws -> ResponseRepresentable腾仅。通過導(dǎo)入HTTP模塊,可以獲得請求(Request)和響應(yīng)(ResponseRepresentable)套利。

import Vapor
let drop = try Droplet()

let hc = HelloController()
drop.get("hello", handler: hc.sayHello)

由于sayHello”方法的簽名與drop.get方法的閉包簽名相匹配推励,我們可以直接傳遞它。

類型安全(Type Safe)

您還可以使用帶有類型安全路由的控制器方法肉迫。

final class HelloController {
    ...

    func sayHelloAlternate(_ req: Request) -> ResponseRepresentable {
        let name: String = try req.parameters.next(String.self)
        return "Hello, \(name)"
    }
}

我們在HelloController中添加一個名為sayHelloAlternate的新方法验辞,從請求的參數(shù)中獲取一個String

let hc = HelloController()
drop.get("hello", String.parameter, handler: hc.sayHelloAlternate)

由于dropget接受了一個簽名(Request) throws -> ResponseRepresentable喊衫,我們的方法現(xiàn)在可以作為這條路線的終止跌造。

筆記
在路由參數(shù)(Routing Parameters)部分閱讀更多關(guān)于類型安全路由的信息。

資源(Resources)

符合ResourceRepresentable的控制器可以很容易地作為一個RESTful資源被注冊到路由器族购。讓我們來看一個UserController的例子壳贪。

final class UserController {
    func index(_ req: Request) throws -> ResponseRepresentable {
        return try User.all().makeJSON()
    }

    func show(_ req: Request) throws -> ResponseRepresentable {
        let user = try req.parameters.next(User.self)
        return user
    }
}

這是一個典型的用戶控制器,它有一個indexshow路徑寝杖。索引返回所有用戶的JSON列表撑碴,并顯示返回單個用戶的JSON數(shù)據(jù)。

我們可以像這樣注冊控制器:

let users = UserController()
drop.get("users", handler: users.index)
drop.get("users", User.self, handler: users.show)

但是朝墩,ResourceRepresentable使得這種標(biāo)準(zhǔn)的RESTful結(jié)構(gòu)很容易醉拓。

extension UserController: ResourceRepresentable {
    func makeResource() -> Resource<User> {
        return Resource(
            index: index,
            show: show
        )
    }
}

符合ResourceRepresentableUserController需要indexshow方法的簽名與Resource<User>的期望相匹配。

現(xiàn)在收苏,UserController可以滿足ResourceRepresentable的需要亿卤,注冊路由很容易。

let users = UserController()
drop.resource("users", users)

drop.resource將只負(fù)責(zé)注冊由調(diào)用makeResource()所提供的路由鹿霸。在這種情況下排吴,只提供indexshow路徑。

Note
drop.resource還為選擇項(OPTIONS)請求增加了有用的缺省值懦鼠。這些可以被重載钻哩。

行動(Actions)

下面是一個描述所有可用操作的表。

Action Method Path Note
index GET /users Returns all users, optionally filtered by the request data.
store POST /users Creates a new user from the request data.
show GET /users/:id Returns the user with the ID supplied in the path.
replace PUT /users/:id Updates the specified user, setting any fields not present in the request data to nil.
update PATCH /users/:id Updates the specified user, only modifying fields present in the request data.
delete DELETE /users/:id Deletes the specified user.
clear DELETE /users Deletes all users, optionally filtered by the request data.
create GET /users/create Displays a form for creating a new user.
edit GET /users/:id/edit Displays a form for editing the specified user.

提示
replaceupdate之間的差異是很微妙但很重要的:如果請求數(shù)據(jù)中不存在某個字段(例如肛冶,用戶的年齡丟失了)街氢,update應(yīng)該不會更新該字段,因為replace應(yīng)該將其設(shè)置為nil睦袖。如果replace請求中缺少所需的數(shù)據(jù)珊肃,則應(yīng)該拋出一個錯誤。

文件夾(Folder)

控制器可以在應(yīng)用程序的任何地方進(jìn)行,但它們通常存儲在應(yīng)用App/Controllers/目錄中伦乔。

提示
如果您正在構(gòu)建一個大型應(yīng)用程序厉亏,您可能希望在一個單獨(dú)的模塊中創(chuàng)建控制器。這將允許您在控制器上執(zhí)行單元測試烈和。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末爱只,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子招刹,更是在濱河造成了極大的恐慌虱颗,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔗喂,死亡現(xiàn)場離奇詭異,居然都是意外死亡高帖,警方通過查閱死者的電腦和手機(jī)缰儿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來散址,“玉大人乖阵,你說我怎么就攤上這事≡铮” “怎么了瞪浸?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吏祸。 經(jīng)常有香客問我对蒲,道長,這世上最難降的妖魔是什么贡翘? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任蹈矮,我火速辦了婚禮,結(jié)果婚禮上鸣驱,老公的妹妹穿的比我還像新娘泛鸟。我一直安慰自己,他們只是感情好踊东,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布北滥。 她就那樣靜靜地躺著,像睡著了一般闸翅。 火紅的嫁衣襯著肌膚如雪再芋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天坚冀,我揣著相機(jī)與錄音祝闻,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛联喘,可吹牛的內(nèi)容都是我干的华蜒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼豁遭,長吁一口氣:“原來是場噩夢啊……” “哼叭喜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蓖谢,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤捂蕴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后闪幽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啥辨,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年盯腌,在試婚紗的時候發(fā)現(xiàn)自己被綠了溉知。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡腕够,死狀恐怖级乍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情帚湘,我是刑警寧澤玫荣,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站大诸,受9級特大地震影響捅厂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜资柔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一恒傻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧建邓,春花似錦盈厘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至注簿,卻和暖如春契吉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诡渴。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工捐晶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留菲语,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓惑灵,卻偏偏與公主長得像山上,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子英支,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容