Skip to content

Instantly share code, notes, and snippets.

@edgarfgp
Last active July 29, 2021 17:05
Show Gist options
  • Save edgarfgp/d9e98bede10b7ac8cfb8dd51620b0dfc to your computer and use it in GitHub Desktop.
Save edgarfgp/d9e98bede10b7ac8cfb8dd51620b0dfc to your computer and use it in GitHub Desktop.
FSharp Reactive http calls
open System.Reactive.Disposables
#r "nuget: Ply"
#r "nuget: System.Text.Json, 5.0.2"
#r "nuget: FSharp.SystemTextJson, 0.17.4"
#r "nuget: Fsharp.Control.Reactive, 5.0.2"
open FSharp.Control.Reactive
open FSharp.Control.Tasks
open System.Net.Http
open System.Text.Json.Serialization
open System.Text.Json
let disposables = new CompositeDisposable()
let currencies = [|
"bgn"
"brl"
"cad"
"chf"
"cny"
"czk"
"dkk"
"eur"
"gbp"
"hkd"
"hrk"
"huf"
"idr"
"ils"
"inr"
"isk"
"jpy"
"krw"
"mxn"
"myr"
"nok"
"nzd"
"php"
"pln"
"ron"
"rub"
"sek"
"sgd"
"thb"
"usd"
"zar" |]
[<JsonFSharpConverter>]
type Country = {
flag: string
currencies: Currency array
}
and Currency =
{ code: string option
name: string option
symbol: string option }
let createJsonOption : JsonSerializerOptions =
let options = JsonSerializerOptions()
options.Converters.Add(JsonFSharpConverter())
options
let deserialize<'T> (json: string) =
try
JsonSerializer.Deserialize<'T>(json, createJsonOption)
|> Ok
with
| ex -> Error ex.Message
let makeRequest currency =
task {
use client = new HttpClient()
let! response = client.GetAsync($"https://restcountries.eu/rest/v2/currency/%s{currency}") |> Async.AwaitTask
response.EnsureSuccessStatusCode () |> ignore
let! content = response.Content.ReadAsStringAsync() |> Async.AwaitTask
let result = deserialize<Country[]>(content)
return result // prints the 100 post array to the console
}
|> Async.AwaitTask
// we run synchronously
// to allow the fsi to finish the pending tasks
|> Async.RunSynchronously
let result =
currencies
|> Observable.toObservable
|> Observable.flatmapAsync
(fun currency ->
async {
let result = makeRequest currency
return result
})
|> Observable.subscribe(fun c ->
match c with
| Ok result ->
result
|> Seq.iter(fun country -> printfn $"{country}")
| Error error -> printfn $"{error}")
result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment