How do you send an API request in Vapor 3 with the HTTPRequest
struct?
I tried variations of the following code..
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)
}
The compile error Cannot convert value of type '(HTTPClient) -> EventLoopFuture<HTTPResponse>' to expected argument type '(HTTPClient) -> _'
I have tried other variations of code that worked.
Vapor 3 Beta Example Endpoint Request
let client = try req.make(Client.self)
let response: Future<Response> = client.get("http://example.vapor.codes/json")
I read and re-read:
Your problem is .map(to: HTTPResponse.self)
. Map needs to transform its result into a new result regularly, like you would map
an array. However, the result of your map-closure returns an EventLoopFuture<HTTPResponse>
. This results in your map
function returning an EventLoopFuture<EventLoopFuture<HTTPResponse>>
.
To avoid this complexity, use 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)
}
EDIT: If you want to use the Content APIs you can do so like this:
let data = httpRes.flatMap(to: ExampleData.self) { httpResponse in
let response = Response(http: httpResponse, using: req)
return try response.content.decode(ExampleData.self)
}