1

我有一个Model符合Content

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
    }
}

这可以从数据库中获取并直接从路由返回,因此客户端以 JSON 形式接收用户。

现在我想向用户添加一个附加属性,它不存储在数据库中,而是一个固定值,或者只是在从数据库加载用户后添加:

final class User: Model, Content {
    // ...
    var someOther: String = "hello"
    // ...
}

或者

final class User: Model, Content {
    // ...
    var someOther: String? // set later
    // ...
}

现在的问题是这个属性永远不会添加到 JSON 中,所以客户端只获取用户的id不是. 我该如何解决?emailsomeProperty

4

1 回答 1

2

当您想从您的客户端发送或接收与您的模型具有不同表示的数据时,通常的做法是定义一个自定义类型,然后您可以在模型类型之间进行转换。

鉴于此,您将定义一个User.Response符合的新类型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,或其他字段属性包装器,它不会被编码。

于 2020-09-11T15:38:55.967 回答