问题描述
Content
这可以从数据库中获取并直接从路由返回,因此客户端将用户作为JSON接收。
现在,我想向用户添加一个附加属性,该属性不存储在数据库中,而是一个固定值,或者只是在从数据库中加载用户之后才添加:
import Vapor
import Fluent
final class User: Model,Content {
static let schema = "user"
@ID(key: .id)
var id: UUID?
@Field(key: "email")
var email: String
init() { }
init(id: UUID? = nil,email: String) {
self.id = id
self.email = email
}
}
或
final class User: Model,Content {
// ...
var someOther: String = "hello"
// ...
}
现在的问题是此属性从未添加到JSON,因此客户端仅获取用户的final class User: Model,Content {
// ...
var someOther: String? // set later
// ...
}
和id
,而 NOT email
。我该如何解决?
解决方法
当您要从客户端发送或接收的数据与模型具有不同的表示形式时,通常的做法是定义一个自定义类型,然后可以与该模型类型相互转换。
鉴于此,您将定义一个符合Content
而不是User
模型的新extension User {
struct Response: Content {
let id: UUID
let email: String
let otherValue = "Hello World"
}
}
func user(request: Request) throws -> EventLoopFuture<User.Response> {
return User.find(UUID(),on: request.db).flatMapThrowing { user in
guard let id = user.id else {
throw Abort(.internalServerError,"User is missing ID")
}
return User.Response(id: id,email: user.email)
}
}
类型,然后从您的路线中返回它。
ID
未从模型中编码您添加的附加值的原因是,模型类型的默认编码器会遍历字段属性并对这些属性进行编码,因此,如果您的属性不使用其中一个Field
,Parent
,Children
,workflow_next_step
或其他字段属性包装程序,将不会对其进行编码。