使用Swift4+Vapor寫(xiě)后端-示例&套路

前言

上一篇我們初步了解了Droplet和Route,本篇中我們一起寫(xiě)一些簡(jiǎn)單的get和post請(qǐng)求部念,以及我總結(jié)的一些套路弃酌。因?yàn)楸救艘彩浅鯇W(xué),沒(méi)有任何后端開(kāi)發(fā)經(jīng)驗(yàn)儡炼,所有難免出現(xiàn)錯(cuò)誤妓湘,大蝦們多多指正。

常見(jiàn)請(qǐng)求

get/post請(qǐng)求

返回字符串

drop.get("get","string") { req in
    return "Hello, world!"
}

返回JSON

drop.get("get","json") { req in
     var json = JSON()
     try json.set("hello", "world")
     return json
}

獲取request中數(shù)據(jù)

drop.get("get","info") { req in
     var json = JSON()
     let name = req.data["name"]?.string
     let age = req.data["age"]?.int
     let isVip = req.data["isVip"]?.bool
     try json.set("name", name)
     try json.set("age", age)
     try json.set("isVip", isVip)
     return json
}

post請(qǐng)求同上處理乌询。

項(xiàng)目路由處理常見(jiàn)套路

單一文件

demo或者測(cè)試項(xiàng)目中業(yè)務(wù)邏輯很少榜贴,不需要統(tǒng)一管理時(shí),所有的路由直接寫(xiě)main.swift中就可以了楣责。
如: main.swift


let config = try Config()
try config.setup()
let drop = try Droplet(config)

// 注冊(cè)路由
// get 示例
drop.get("welcome") { request in
    return "Hello"
}

// post 示例
drop.post("form") { request in
    return "Submitted with a POST request"
}

// 路由組 示例 1
drop.group("v1") { v1 in

    // get 
    v1.get("users") { request in
        // get the users
    }

    // post 
    drop.post("form") { request in
        return "Submitted with a POST request"
    }
}

// 路由組 示例 2
let v1 = drop.grouped("v1")

// get 
v1.get("users") { request in
    // get the users
}

// post 
v1.post("form") { request in
    return "Submitted with a POST request"
}

// 運(yùn)行
try drop.run()

vapor模板中的實(shí)現(xiàn)

當(dāng)直接使用vapor new Hello --template=api創(chuàng)建一個(gè)名為“hello”的vapor默認(rèn)的模板項(xiàng)目時(shí)竣灌,內(nèi)部已經(jīng)存在了部分樣板代碼聂沙。
具體就是通過(guò)給ConfigDroplet添加extension初嘹,在extension中實(shí)現(xiàn)路由注冊(cè)及汉。具體代碼參考Sources/App/Setup/目錄下Config+Setup.swiftDroplet+Setup.swift文件。

Droplet+Setup.swift實(shí)現(xiàn)一個(gè)setup方法去注冊(cè)路由

extension Droplet {
    public func setup() throws {
        try setupRoutes()
        // Do any additional droplet setup
        
    }

    func setupRoutes() throws {
        get("hello") { req in
            var json = JSON()
            try json.set("hello", "world")
            return json
        }

        post("posttest") { req in
    
        }
    }
}

工具類(lèi)統(tǒng)一注冊(cè)路由

通過(guò)一個(gè)工具類(lèi)如:RouteTool屯烦、Router 等等(命名隨意)坷随,來(lái)統(tǒng)一注冊(cè)路由,以MVC的方式搭建項(xiàng)目驻龟。

首先在main.swift中温眉,我們定義全局變量apiv1翁狐、v2等(根據(jù)實(shí)際需求)管理路由組类溢。如:

let config = try Config()
try config.setup()
let drop = try Droplet(config)

/// 基礎(chǔ)api
let api   = drop.grouped("api")
let v1    = api.grouped("v1")
let v2    = api.grouped("v2")

/// 路由
RouteTool.setUp()
try drop.run()

然后如上述代碼中RouteTool.setUp(),我們創(chuàng)建一個(gè)路由工具RouteTool露懒,并為其實(shí)現(xiàn)一個(gè)setUp方法來(lái)為不同的控制器統(tǒng)一注冊(cè)路由闯冷。示例:


struct RouteTool {
    static func setUp() {
        // 注冊(cè)業(yè)務(wù)
        SignController().registeredRouting()
        // 用戶(hù)業(yè)務(wù)
        UserController().registeredRouting()
        // 驗(yàn)證碼
        VerifyCodeController().registeredRouting()
        // 評(píng)論業(yè)務(wù)
        CommentController().registeredRouting()
        ···等等
    }
}

然后我們?cè)诰唧w的控制器里,完成路由注冊(cè)懈词、數(shù)據(jù)請(qǐng)求的具體實(shí)現(xiàn)蛇耀。比如我們創(chuàng)建SignUpController,用來(lái)處理用戶(hù)注冊(cè)的業(yè)務(wù)坎弯。
SignUpController.swift中纺涤,我們實(shí)現(xiàn)處理請(qǐng)求。方法內(nèi)部的業(yè)務(wù)代碼此處使用...省略抠忘,并非本篇重點(diǎn)撩炊。

class SignController {

    // 對(duì)外提供統(tǒng)一注冊(cè)路由的方法
    public func registeredRouting() {
        v1.post("signup", handler: self.signup)
        v1.post("password","reset", handler: self.resetPassWord)
        v1.post("password","change", handler: self.changePassWord)
    } 

    // 用戶(hù)注冊(cè)
    func signup(_ request: Request) throws -> ResponseRepresentable {
        ...
    }

    // 重置密碼
    func resetPassWord(_ request: Request) throws -> ResponseRepresentable { 
        ...
    }
    // 更改密碼
    func changePassWord(_ request: Request) throws -> ResponseRepresentable {
        ...
    }
    ...等等其他業(yè)務(wù)

}

通過(guò)RouteCollection協(xié)議來(lái)注冊(cè)路由組

同樣的,我們使用上一節(jié)中的SignController作代碼示例褐桌。遵守RouteCollection協(xié)議并實(shí)現(xiàn)func build(_ builder: RouteBuilder)協(xié)議方法衰抑。

class SignController: RouteCollection {

    func build(_ builder: RouteBuilder) throws {
        let api = builder.grouped("api")
        let v1 = api.grouped("v1")
        v1.post("signup", handler: self.signUp)
        v1.post("password","reset", handler: self.resetPassWord)
        v1.post("password","change", handler: self.changePassWord)
    }

    // 用戶(hù)注冊(cè)
    func signup(_ request: Request) throws -> ResponseRepresentable {
        ...
    }

    // 重置密碼
    func resetPassWord(_ request: Request) throws -> ResponseRepresentable { 
        ...
    }
    // 更改密碼
    func changePassWord(_ request: Request) throws -> ResponseRepresentable {
        ...
    }
    ...等等其他業(yè)務(wù)
}

這時(shí)候我們就可以在main.swift中通過(guò)collection(<#T##c: (EmptyInitializable & RouteCollection).Protocol##(EmptyInitializable & RouteCollection).Protocol#>)來(lái)注冊(cè)路由組了。

let config = try Config()
try config.setup()
let drop = try Droplet(config)

// 注冊(cè)路由組
let signVC = SignController()
drop.collection(signVC)

try drop.run()

我們也可以為控制器實(shí)現(xiàn)一個(gè)extension并遵守EmptyInitializable協(xié)議荧嵌,這樣做的目的是注冊(cè)路由時(shí)我們無(wú)需實(shí)例化該控制器呛踊。

extension SignController: EmptyInitializable { }

此時(shí)我們?cè)谝陨献?cè)路由組的示例代碼中就不需要實(shí)例化SignController了。

drop.collection(SignController.self)

最后

本篇是我在閱讀文檔和其他開(kāi)源項(xiàng)目時(shí)總結(jié)的一些小套路啦撮,畢竟我也沒(méi)有后端開(kāi)發(fā)經(jīng)驗(yàn)谭网,文中若出現(xiàn)錯(cuò)誤,歡迎批評(píng)指正赃春。

相關(guān)參考

vapor文檔

開(kāi)源項(xiàng)目SRSQ

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末愉择,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凉逛,死亡現(xiàn)場(chǎng)離奇詭異脱盲,居然都是意外死亡适肠,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人谦趣,你說(shuō)我怎么就攤上這事∽浚” “怎么了前鹅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)峭梳。 經(jīng)常有香客問(wèn)我舰绘,道長(zhǎng),這世上最難降的妖魔是什么延赌? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任除盏,我火速辦了婚禮叉橱,結(jié)果婚禮上挫以,老公的妹妹穿的比我還像新娘。我一直安慰自己窃祝,他們只是感情好掐松,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著粪小,像睡著了一般大磺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上探膊,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天杠愧,我揣著相機(jī)與錄音,去河邊找鬼逞壁。 笑死流济,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腌闯。 我是一名探鬼主播绳瘟,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼姿骏!你這毒婦竟也來(lái)了糖声?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蘸泻,沒(méi)想到半個(gè)月后琉苇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悦施,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年翁潘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歼争。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拜马,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沐绒,到底是詐尸還是另有隱情俩莽,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布乔遮,位于F島的核電站扮超,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蹋肮。R本人自食惡果不足惜出刷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坯辩。 院中可真熱鬧馁龟,春花似錦、人聲如沸漆魔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)改抡。三九已至矢炼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阿纤,已是汗流浹背句灌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欠拾,地道東北人胰锌。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像清蚀,于是被迫代替她去往敵國(guó)和親匕荸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • warning 本篇作為vapor文檔基礎(chǔ)篇枷邪,讀起來(lái)很無(wú)聊榛搔,很漫長(zhǎng)诺凡,很空洞。為了后面的vapor生活践惑,務(wù)必認(rèn)真學(xué)習(xí)...
    范范飯?zhí)叵?/span>閱讀 951評(píng)論 0 0
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理腹泌,服務(wù)發(fā)現(xiàn),斷路器尔觉,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 這一個(gè)星期沒(méi)有一天是閑下來(lái)的凉袱。即使沒(méi)有出去,也是手不離機(jī)侦铜。挺喜歡這種充實(shí)而又忙碌的感覺(jué)专甩。 一個(gè)人在努力的時(shí)候,你狀...
    莉莉說(shuō)閱讀 258評(píng)論 0 0
  • 建亩ど裕~預(yù)測(cè)~ 一環(huán)扣一環(huán)呀
    無(wú)隱閱讀 94評(píng)論 0 0