蒸气3-发送HTTPRequest

时间:2019-03-19 16:09:05

标签: vapor server-side-swift

如何在Vapor 3中使用HTTPRequest结构发送API请求?

我尝试了以下代码的变体。

var headers: HTTPHeaders = .init()
let body = HTTPBody(string: a)            
let httpReq = HTTPRequest(
    method: .POST,
    url: URL(string: "/post")!,
    headers: headers,
    body: body)

let httpRes: EventLoopFuture<HTTPResponse> = HTTPClient.connect(hostname: "httpbin.org", on: req).map(to: HTTPResponse.self) { client in
    return client.send(httpReq)
}

编译错误Cannot convert value of type '(HTTPClient) -> EventLoopFuture<HTTPResponse>' to expected argument type '(HTTPClient) -> _'

我尝试了其他有效的代码变体。

Vapor 3 Beta Example Endpoint Request

let client = try req.make(Client.self)

let response: Future<Response> = client.get("http://example.vapor.codes/json")

我阅读并重新阅读:

2 个答案:

答案 0 :(得分:5)

您的问题是.map(to: HTTPResponse.self)。 Map需要定期将其结果转换为新结果,就像map数组一样。但是,关闭地图的结果将返回EventLoopFuture<HTTPResponse>。这将导致您的map函数返回一个EventLoopFuture<EventLoopFuture<HTTPResponse>>

为避免这种复杂性,请使用flatMap

var headers: HTTPHeaders = .init()
let body = HTTPBody(string: a)            
let httpReq = HTTPRequest(
    method: .POST,
    url: URL(string: "/post")!,
    headers: headers,
    body: body)

let client = HTTPClient.connect(hostname: "httpbin.org", on: req)

let httpRes = client.flatMap(to: HTTPResponse.self) { client in
    return client.send(httpReq)
}

编辑: 如果您想使用Content API,可以这样做:

let data = httpRes.flatMap(to: ExampleData.self) { httpResponse in
    let response = Response(http: httpResponse, using: req)
    return try response.content.decode(ExampleData.self)
}

答案 1 :(得分:2)

HTTPClient.connect返回Future<HTTPClient>,并且它映射到Future<HTTPResponse>而不是EventLoopFuture<HTTPResponse>

如果您期望使用单个HTTPResponse,请使用HttpClient.send而不是HTTPClient.connect

如果您期望多个HTTPResponse,则必须更改.map(to: HTTPResponse.self)才能正确映射到EventLoopFuture<HTTPResponse>