查询在 Vapor 中是如何工作的?

How query works in Vapor?

如果基于 facebook 用户 ID 已经存在,如何 return 用户,如果 Vapor 中不存在,如何创建新用户?您可以看到我是如何尝试获取数据的,但出现错误。

final class User: Content {
    var id: Int?
    var fbId: String

    init(id: Int? = nil, fbId: String) {
        self.id = id
        self.fbId = fbId
    }
}

router.get("user") { (request) -> Future<User> in
    return Future.map(on: request) { () -> User in
        let fbId = try request.query.get(String.self, at: "fbId")
        return User.query(on: request).filter(\.fbId == fbId).first().map { (user) -> (U) in
            if user == nil {
                user = User(fbId: fbId)
            }
            return user
        }
    }
}

你这里发生了一些事情。首先,您不需要第一个 Future.map - 不确定它在做什么。

然后你遇到了编译器的问题 - 你必须 return 在每个闭包和函数中使用相同的类型,这很尴尬,因为如果你已经有一个用户,你可以 return ,如果不需要,则需要创建并保存一个 returns Future<User>,这与 User.

不同

所以要回答你的问题,U 应该有 User,但你真的想将 first().map 更改为 first().flatMap 在这种情况下 U变成 Future<User>。然后你可以这样做:

router.get("user") { req -> Future<User> in
    let fbID = try req.query.get(String.self, at: "fbId")
    return User.query(on: req).filter(\.fbId == fbID).first().flatMap { user in
        let returnedUser: Future<User>
        if let foundUser = user {
            returnedUser = req.future(foundUser)
        } else {
            let newUser = User(fbId: fbID)
            returnedUser = newUser.save(on: req)
        }
        return returnedUser
    }
}

为您解决问题。希望对您有所帮助!

.map { (user) -> (U) in

这定义了你得到一个 user 到闭包中并且必须 return 一个 U。在您的示例中,您想要 return a User(因此将 U 更改为 User)。

如果您想创建用户(如果是 nil),您可能还想将其存储在数据库中?如果是这种情况,您必须将 map 更改为 flatMap 并像这样更新:

.flatMap { (user) -> EventLoopFuture<User> in
  if user == nil {
    return User(fbId: fbId).save(on: req)
  }
  return req.future(user)
}