惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
I
InfoQ
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
博客园 - Franky
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园_首页
罗磊的独立博客
V
V2EX
李成银的技术随笔
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
True Tiger Recordings
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
F
Fox-IT International blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
Microsoft Research Blog - Microsoft Research
Know Your Adversary
Know Your Adversary
爱范儿
爱范儿
The Register - Security
The Register - Security
G
Google Developers Blog
The Hacker News
The Hacker News
Malwarebytes
Malwarebytes
S
Securelist
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
博客园 - 叶小钗
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 聂微东
T
Threatpost
博客园 - 【当耐特】
D
Docker
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V
Visual Studio Blog
C
Cisco Blogs
IT之家
IT之家
S
Security Archives - TechRepublic
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志

isaced

使用 TypeScript 构建的 appstore-connect-sdk 我用 SwiftUI 写了一个 V2ex 客户端 Docker 容器化多应用部署 Swift Server-side SDWebImage 为什么无法读取 webpmux 生成的 WebP 动图? [译] 探索 Swift 4 中新的 String API 对一个 Django 站点做 ab 压力测试 fir-mac 开发笔记 iOS10 Safari 引导用户信任企业签名 Swift Web 开发之 Vapor - 模版 Leaf(三) HoloLens 初体验 Swift Web 开发之 Vapor - 入门(一) Jenkins for iOS 搭建日记 iOS HOOK 注入与重签名 Xcode 使用 Configuration 来配置不同的项目环境 图床从SAE迁移到七牛 给 UIProgressView 脱掉那层微弱的渐变 初用 CocoaAsyncSocket 记一次 SQLite 性能优化 有多色 - 开发小记 海岛风情 - 泰国普吉岛六日游 EGOCache 源码解析 日语五十音假名临摹校验算法 [iOS] UITextView 追加文字自动跳到顶部解决方法 Cocoa 新的依赖管理工具:Carthage 新年快乐! 博客主机换到搬瓦工 写了个iOS小游戏:有多色 iOS 后台任务之 Long-running background task 悄悄的就必须用 XCode 5.1.1 上传了! HTTP Content-type 与 AFNetworking Objective-Cloud 初体验(1) 掌中站上架小记 NSLoger 上线了 Python Markdown 做语法限制 Nginx + Gunicorn + Django 部署小记 用Shell脚本批量裁剪App Icon各个尺寸 LaunchRocket使用小记 用宏提速NSCoding 2014新年伊始:近期读过的好文推荐 [iOS] stringWithFormat 和 initWithFormat 有何不同? Apache + Flask + mod_wsgi + Koding 部署小记 收集几个Objective-C的HTML解析库 NSMapTable: 不只是一个能放weak指针的 NSDictionary 2013,再见! Emlog到Typecho的迁移工具:emlog2typecho [iOS]给上拉下拉刷新PullToRefresh做本地化 [iOS]代码推荐:大图缩放视图 - Vertigo iOS:hidesBottomBarWhenPushed的正确用法 Xcode 5新的Interface Builder,你准备好了吗? [翻译]如何使用Django创建简单的博客 我的Mac音乐播放器 初识 NSDataDetector Objective-C 计算代码运行时间 WordPress上传文件自动重命名 iOS:仿jing.fm的音乐播放视图 我的啃黑苹果之路 归档 关于 搜索 项目
Swift Web 开发之 Vapor - 路由(二)
2017-03-04 · via isaced

Featured image of post Swift Web 开发之 Vapor - 路由(二)

上篇文章带大家基本了解了一下开始一个 Vapor 项目的流程,本篇紧接着来说说在所有 Web 框架中都最关键的 “路由”,因为 “路由” 模块在 Web 项目中担任很重要的角色,所以很多语言的 Web 框架都把 “路由” 抽离到框架层,从而减少开发者的工作量,一个设计得易用强大的 “路由” 系统也会给相应给框架增添不少色彩。

Web 开发中的路由这个概念简单来说就是 URL 路径到具体处理函数之间的映射,只有设定好了路由,访问者才能在浏览器根据相关 URL 规则进行页面跳转和访问,Vapor 对路由做了很多实用性设计,包括路由的构建、路由组、类型安全的路由参数、路由集合等等,希望看完本篇文章你能用 Vapor 写出一些简单的路由,我们先来看看 Vapor 最简单的路由注册。

Droplet

注册路由之前我们需要知道 Droplet 这个类,每个程序都应该有一个它的实例,控制着整个程序的生命周期,之后我们会通过 droplet 来注册路由,添加 provider,添加中间件 (middleware) 等等。 droplet 的初始化很简单,一个空程序看起来就像这样:

import Vapor
let drop = Droplet()
// your magic here
drop.run()

注册路由

注册一个最基本的路由通过对全局 Droplet 对象调用一个方法,指定路径和一个闭包来接收操作处理。

drop.get("welcome") { request in
    return "Hello"
}

我们通过调用 get() 方法来注册了一个路径为 /welcome 的路由,并返回了 “Hello” 这个字符串到浏览器,当然我们除了 get 还可以其他的标准 HTTP 方法,比如 postputpatchdeleteoptions

另外我们还可以使用 add() 方法来注册路由,以接收第一个参数 Method 作为 HTTP 方法来动态注册路由,Method 是一个枚举,包含了上述所列的 HTTP 标准方法,代码看起来是这样:

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"
}

像这个例子因为用了 * 尾随参数,可以匹配到如下所有路径:

  • /anything
  • /anything/foo
  • /anything/foo/bar
  • /anything/foo/bar/baz

Request

每个路由的闭包都会有一个 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

每个路由的闭包中可以返回三种类型的内容,ResponseResponseRepresentablethrow,你可以你可以返回自己所需的 HTTP 状态码、URL 重定向、JSON 等,基本涵盖日常所需的请求返回。

Response

Response 是 Vapor 中 HTTP 模块中定义的基于 Message 的类,有很多构造方法方便我们自定义 response 返回:

// 重定向
Response(redirect: "http://vapor.codes")

// JSON
Response(status: .ok, json: JSON(["hello":"world"]))

// String
Response(body: "hello")
ResponseRepresentable

ResponseRepresentable 是一个协议,任何遵循这个协议的对象均可在路由中返回,就像之前例子中我们直接返回了字符串,就是因为 Vapor 默认给 String 实现了 ResponseRepresentable 协议,让我们可以方便的在闭包中直接返回字符串,类似的还有 JSONModel 对象。

throw

另外一大特性就是可以直接在路由中抛出异常,我们可以 throw 任何遵从 Swift.Error 协议的对象,当然 Vapor 已经为我们封装好了几个常用的 Error 来方便我们抛出异常。

drop.get("404") { request in
    throw Abort.notFound
}

当我们请求这个地址的时候一般会看到一个 Vapor 默认提供的错误页面,还挺漂亮的,如果不想用 Vapor 提供的默认错误页面,我们可以从 drop.middleware 中移除 AbortMiddleware 并添加自己的实现即可。

vapor404

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 提供了路由组的概念,通常用来集中组织一组相同前缀,添加中间件,限制主机名,或者集中管理的路由,路由组有两个类型:GroupGrouped

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。

之前开的坑在用 Vapor 写一个博客程序 NSPress,如果大家有兴趣欢迎讨论。