Как использовать HttpClient из F #?
Я новичок в F # и застрял в понимании async в F # с точки зрения разработчика С#. Скажем, что в С# следующий фрагмент:
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
Как написать то же самое в F #?
Ответы
Ответ 1
Вот функция, которая должна делать то, что вы ищете (обратите внимание, что вам придется обернуть код в асинхронном выражении вычисления, чтобы использовать синтаксис let!):
let getAsync (url:string) =
async {
let httpClient = new System.Net.Http.HttpClient()
let! response = httpClient.GetAsync(url) |> Async.AwaitTask
response.EnsureSuccessStatusCode () |> ignore
let! content = response.Content.ReadAsStringAsync() |> Async.AwaitTask
return content
}
Ответ 2
Вы должны хотя бы прочитать и знать установленные шаблоны в Http.fs, если вы что-то делаете с HttpClient
в F #.
[См. комментарии] TL; DR... , но остерегайтесь доли. Как отмечает @pimbrouwers, следует отметить, что вам не обязательно использовать его, хотя - поднаборы и/или развитие вашего собственного набора помощников в вашем контексте могут привести вас к более подходящей абстракции (и принести вам преимущества обучения в пути).
К этому моменту: в F # считается идиоматической практикой хранить редко используемых и/или чрезмерно специфичных помощников в нецентральном месте.
Ответ 3
Вы можете использовать async
:
let readString (url: Uri) = async {
let httpClient = new HttpClient();
let! response = httpClient.GetAsync(url) |> Async.AwaitTask
response.EnsureSuccessStatusCode() |> ignore
return! response.Content.ReadAsStringAsync() |> Async.AwaitTask
}
Ответ 4
Просто мои два цента. Но я понимаю, что мы должны обращаться с HttpRequestException
при использовании EnsureSuccessStatusCode()
.
Ниже приведено начало переноса модуля HttpClient
, который буферизует ответ URL-адреса в string
и безопасно переносит в Result<'a, 'b>
для повышения отказоустойчивости.
module Http =
open System
open System.Net.Http
let getStringAsync url =
async {
let httpClient = new HttpClient()
// This can be easily be made into a HttpClientFactory.Create() call
// if you're using >= netcore2.1
try
use! resp = httpClient.GetAsync(Uri(url), HttpCompletionOption.ResponseHeadersRead) |> Async.AwaitTask
resp.EnsureSuccessStatusCode |> ignore
let! str = resp.Content.ReadAsStringAsync() |> Async.AwaitTask
return Ok str
with
| :? HttpRequestException as ex -> return ex.Message |> Error
}
Ответ 5
Просто используйте FSharp.Control.FusionTasks
, и у вас будет четкий синтаксис без |> Async.AwaitTask
, как
let httpClient = new System.Net.Http.HttpClient ()
let getAsync (url:string) =
async {
let! response = httpClient.GetAsync url
response.EnsureSuccessStatusCode () |> ignore
let! content = response.Content.ReadAsStringAsync ()
return content
}