Vapor 3 - отправьте HTTPRequest - PullRequest
6 голосов
/ 19 марта 2019

Как отправить запрос API в Vapor 3 со структурой HTTPRequest?

Я пробовал варианты следующего кода ..

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

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

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

Я читаю и перечитываю:

Ответы [ 2 ]

5 голосов
/ 19 марта 2019

Ваша проблема .map(to: HTTPResponse.self).Карта должна регулярно преобразовывать свой результат в новый результат, как если бы вы 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)
}
2 голосов
/ 19 марта 2019

HTTPClient.connect возвращает Future<HTTPClient> и сопоставляется с Future<HTTPResponse>, а не EventLoopFuture<HTTPResponse>.

Если вы ожидаете одного HTTPResponse, используйте HttpClient.send вместо HTTPClient.connect.

Если вы ожидаете несколько HTTPResponse с, тогда .map(to: HTTPResponse.self) необходимо изменить, чтобы правильно отобразить на EventLoopFuture<HTTPResponse>

...