我正在阅读《服务器端Swift Vapor Edition》一书,并试图完成第174页的练习。
我有一个名为Poll的结构体,定义如下:
struct Poll: Content, SQLiteUUIDModel, Migration {
var id: UUID?
var title: String
var option1: String
var option2: String
var votes1: Int
var votes2: Int
}
它使用Fluent映射到SQLite数据库中,我正试图编写一个路由,给出这样的post请求:
localhost:8080/轮询/删除/
能够在数据库中找到轮询对象,如果不存在则返回错误,如果存在则删除。这就是我目前解决问题的方法:
router.post("polls", "delete", UUID.parameter) { req -> Future<Poll> in
let id = try req.parameters.next(UUID.self)
return Poll.find(id, on: req).map(to: Poll.self) { poll in
guard let poll = poll else {
throw Abort(.notFound)
}
poll.delete(on: req)
return poll
}
}
让我们把它分解一下:
-
我读取了post请求中传递的UUID(例如。
http://localhost:8080/polls/delete/FBF7FDC2-0ECB-4C1F-AD8F-A62DE68E531B
)
-
我试着找到民意调查
-
如果poll对象为nil(这意味着未找到),则抛出404 not found错误
-
如果我找到了,我会删除投票并返回
这行得通。我可以使用此路线删除民意调查。
但我心里有一些问题:
-
难道删除方法仍然失败?(例如,由于SQLite内部错误)
-
如果是,我可以等到投票被实际删除后再返回吗?
问题是delete方法返回一个EventoopFuture类型的对象。如果它是tupeEventoopFuture的一个对象,我就可以很容易地将其映射到投票。但是由于模板参数是Void,如果我这样修改代码:
router.post("polls", "delete", UUID.parameter) { req -> Future<Poll> in
let id = try req.parameters.next(UUID.self)
return Poll.find(id, on: req).flatMap(to: Poll.self) { poll in
guard let poll = poll else {
throw Abort(.notFound)
}
return poll.delete(on: req).flatMap(to: Poll.self) { poll -> EventLoopFuture<Poll> in
return poll
}
}
}
我收到一个语法错误:“无法将'Void'类型的值转换为'EventoopFuture'类型的闭包结果”。看起来我无法将EventoopFuture对象映射到EventoopFuture。问题只是我想等待删除操作完成后再返回。有解决办法吗?