首页 > 解决方案 > Vapor:使用参数在路由器 POST 调用中调用 REST API

问题描述

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

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

这将正确返回 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'

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

标签: swiftvapor

解决方案


只需更换

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

那么map和 和有什么不一样flatMap

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

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<>?它只是一个承诺,就像一个带有回调的对象。


推荐阅读