在使用Vapor构建API时,请始终使用一种方法来获取对象,
request.parameters.next(type.self)
似乎是一种提取url参数的方法,为什么它从数据库返回结果?从框架的源代码中找不到任何线索。我如何找到答案?谢谢。
答案 0 :(得分:3)
Parameter
协议的样子
public protocol Parameter {
associatedtype ResolvedParameter
static var routingSlug: String { get }
static func resolveParameter(_ parameter: String, on container: Container) throws -> ResolvedParameter
}
当您使任何事情符合Parameter
时,都应实现此功能
static func resolveParameter(_ parameter: String, on container: Container) throws -> ResolvedParameter
应从URL解析字符串参数并返回一些对象。而且由于Parameter
是通用的,因此您可以返回所需的任何类型。
让我们写一个扩展名以使Date
符合Parameter
extension Date: Parameter {
public static func resolveParameter(_ parameter: String, on container: Container) throws -> Date {
guard let timeIntervalSince1970 = TimeInterval(parameter) else {
throw Abort(.notAcceptable, reason: "Unable to parse \"\(parameter)\" parameter")
}
return Date(timeIntervalSince1970: timeIntervalSince1970)
}
}
Parameter
的方法从URL解析String
参数并返回Date
,但是您还可以返回其他内容,例如TimeInterval
因为Parameter
是通用协议
extension Date: Parameter {
public static func resolveParameter(_ parameter: String, on container: Container) throws -> TimeInterval {
guard let timeIntervalSince1970 = TimeInterval(parameter) else {
throw Abort(.notAcceptable, reason: "Unable to parse \"\(parameter)\" parameter")
}
return timeIntervalSince1970
}
}
当您使Fluent模型符合Parameter
时,它的扩展名中已经有Parameter
协议的实现,这就是为什么您不应该手动声明resolveParameter
函数的原因。
让我们看看如果您手动声明resolveParameter
方法(例如, User
模型
extension User {
public static func resolveParameter(_ parameter: String, on container: Container) throws -> Future<User> {
// e.g. User's primary key is UUID
guard let id = UUID(parameter) else {
throw Abort(.notAcceptable, reason: "Unable to parse \"\(parameter)\" into UUID")
}
// getting database connection from pool
return container.requestPooledConnection(to: .psql).flatMap { conn in
// querying user by provided primary key
return User.query(on: conn)
.filter(\.id == id)
.first()
.unwrap(or: Abort(.notFound, reason: "Unable to find user by provided primary key"))
.always {
// will release connection in any case
try? container.releasePooledConnection(conn, to: .psql)
}
}
}
}
如您所见,您可以实现resolveParameter
来返回所需的任何内容。