自定义参数类型

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

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

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:

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就好了:

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对

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