自定义参数类型

首先,在 Sources/App/Models 中,我们新建一个文件 Episode.swift,在这里,定义一个类型 Episode,表示数据库中的视频对象:

swift
struct Episode {
var id: Int
var desc: String

init(id: String) {
if let eid = Int(id) {
self.id = eid
self.desc = "Description of episode \(self.id)"
}
else {
self.id = 0
self.desc = "Invalid episode"
}
}
}

定义路由 /routers

swift
router.get("episodes", Episode.parameter) {
req -> String in
let episode = try req.parameters.next(Episode.self)
return "Episode id: \(episode.id)\nEpisode desc: \(episode.desc)"
}

这次,为了可以通过 try req.parameters.next (Episode.self) 直接通过传入的 ID 得到对应的 Episode 对象。在 Model 中我们要让 Episode 遵从 protocol Parameter:

swift
extension Episode: Parameter {
static func resolveParameter(_ parameter: String,
on container: Container)
throws -> Episode {
return Episode(id: parameter)
}
}

其中:

  • parameter 表示要解析出 Episode 对象的参数,这里也就是我们通过 URL 传递的 ID;
  • container 我们暂时还用不到,所以先忽略它就好了;

这样,我们就可以修改之前的 /episodes 路由了:

让路由返回 JSON

我们只要让 Episode 遵从 protocol Content 就好了:

swift
struct Episode: Content {
var id: Int
var desc: String

init(id: String) {
if let eid = Int(id) {
self.id = eid
self.desc = "Description of episode \(self.id)"
}
else {
self.id = 0
self.desc = "Invalid episode"
}
}
}

剩下的事情,就都交给 Vapor 就好。这样,在 /episode 路由中,我们可以直接返回 Episode 对

swift
router.get("episodes", Episode.parameter) {
req -> Episode in
return try req.parameters.next(Episode.self)
}