Vapor 3 - 发送 HTTPRequest
Vapor 3 - send a HTTPRequest
如何使用 HTTPRequest
结构在 Vapor 3 中发送 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")
我读了又读:
HTTPClient.connect
returns Future<HTTPClient>
并且它映射到 Future<HTTPResponse>
而不是 EventLoopFuture<HTTPResponse>
.
如果您希望获得单个 HTTPResponse
,请使用 HttpClient.send
而不是 HTTPClient.connect
。
如果您需要多个 HTTPResponse
,则必须更改 .map(to: HTTPResponse.self)
以正确映射到 EventLoopFuture<HTTPResponse>
您的问题是.map(to: HTTPResponse.self)
。 Map 需要定期将其结果转换为新结果,就像 map
数组一样。然而,你的地图关闭的结果 returns 一个 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)
}
如何使用 HTTPRequest
结构在 Vapor 3 中发送 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")
我读了又读:
HTTPClient.connect
returns Future<HTTPClient>
并且它映射到 Future<HTTPResponse>
而不是 EventLoopFuture<HTTPResponse>
.
如果您希望获得单个 HTTPResponse
,请使用 HttpClient.send
而不是 HTTPClient.connect
。
如果您需要多个 HTTPResponse
,则必须更改 .map(to: HTTPResponse.self)
以正确映射到 EventLoopFuture<HTTPResponse>
您的问题是.map(to: HTTPResponse.self)
。 Map 需要定期将其结果转换为新结果,就像 map
数组一样。然而,你的地图关闭的结果 returns 一个 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)
}