Vapor:使用参数在路由器 POST 调用内部调用 REST API

Vapor: Call REST API inside router POST call with parameters

所以我正在尝试调用我的 Vapor 端点之一中的第二个端点。我有一个端点,它只是一个 get 并且运行良好:

router.get("status") { req -> Future<ConnectionResponse> in
  let client = try req.make(Client.self)
  let response = client.get("https://url.com/endpoint/")

  return response.flatMap(to: ConnectionResponse.self, { response in
    return try response.content.decode(ConnectionResponse.self)
  })
}

这 returns 正确地是一个 ConnectionResponse json。当我尝试做同样的事情时,但在需要一些参数的 POST 中,我无法弄清楚为什么编译器不允许我 运行:

router.post("purchase") { req -> Future<ConnectionResponse> in
  return try req.content.decode(PurchaseRequest.self).map(to: ConnectionResponse.self, { response in
    let client = try req.make(Client.self)
    let response = client.get("https://url.com/endpoint/")

    return response.flatMap(to: ConnectionResponse.self, { response in
      return try response.content.decode(ConnectionResponse.self)
    })
  })
}

它在 flatMap 上失败说 Cannot convert return expression of type 'EventLoopFuture<ConnectionResponse>' to return type 'ConnectionResponse'

如您所见,purchase GET 调用与 status 相同,除了 POST 参数的初始解码。我究竟做错了什么?

简单替换

return try req.content.decode(PurchaseRequest.self).map(to: ConnectionResponse.self, { response in

return try req.content.decode(PurchaseRequest.self).flatMap(to: ConnectionResponse.self, { response in

完整的工作代码可能如下所示

router.post("purchase") { req -> Future<ConnectionResponse> in
  return try req.content.decode(PurchaseRequest.self).flatMap { response in
    let client = try req.make(Client.self)
    let response = client.get("https://url.com/endpoint/")

    return response.flatMap { response in
      return try response.content.decode(ConnectionResponse.self)
    }
  }
}

那么mapflatMap有什么区别呢?

如果下一个结果是 Future<Something>,则使用

flatMap 例如:

someDatabaseCall(on: container).flatMap { databaseResult1 in
    /// it will return Future<DatabaseResult>
    /// that's why we use `flatMap` above instead of `map`
    return anotherDatabaseCall(on: container) 
}

map 用于非未来结果,例如:

someDatabaseCall(on: container).map { databaseResult1 in
    /// it will return non-future result
    /// that's we use `map` above instead of `flatMap`
    return "hello world" // just simple string
}

什么是Future<>?这只是一个承诺,就像一个带有回调的对象。