request.parameters.next 在 Vapor 机制中如何工作?
How does request.parameters.next work in Vapor mechanism?
使用 Vapor 构建 API 时,始终使用方法来获取对象,
request.parameters.next(type.self)
似乎是提取url参数的方法,为什么它return从数据库中提取结果?无法从框架的源代码中找到任何线索。我怎样才能找到答案?谢谢
这是 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 和 return 某个对象中解析字符串参数作为结果。由于 Parameter
是通用的,您可以 return 任何您想要的类型。
让我们写一个扩展以符合 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 和 returnsDate
解析 String
参数,但你也可以 return 其他东西,例如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
到 return 任何你想要的东西。
使用 Vapor 构建 API 时,始终使用方法来获取对象,
request.parameters.next(type.self)
似乎是提取url参数的方法,为什么它return从数据库中提取结果?无法从框架的源代码中找到任何线索。我怎样才能找到答案?谢谢
这是 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 和 return 某个对象中解析字符串参数作为结果。由于 Parameter
是通用的,您可以 return 任何您想要的类型。
让我们写一个扩展以符合 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 和 returnsDate
解析 String
参数,但你也可以 return 其他东西,例如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
到 return 任何你想要的东西。