Thoth.Fetch icon indicating copy to clipboard operation
Thoth.Fetch copied to clipboard

Create a .Net version of this library

Open MangelMaxime opened this issue 6 years ago • 5 comments

@forki made the proposition to create a .Net version of this library

It would expose Task and use HttpClient under the hood.

I do like this idea

MangelMaxime avatar Sep 11 '19 14:09 MangelMaxime

Love it!

tforkmann avatar Sep 11 '19 14:09 tforkmann

The important bit is that code that accesses backend from fable would look the same as code that accesses additional external services from the backend. It would be a unified model and we could reuse what we have learned.

forki avatar Sep 11 '19 15:09 forki

The important bit is that code that accesses backend from fable would look the same as code that accesses additional external services from the backend

I think it should be do-able except for the configuration part of the request. The things we call properties. I will be able to give more detail when I have a basic version working.

MangelMaxime avatar Sep 11 '19 15:09 MangelMaxime

I am starting to prototype this feature and so I am using this issue for tracking my design ideas etc.

In Thoth.Json v5, I want to explore the idea of having a core library which is runtime independent.

Thoth.Fetch codebase being simpler than Thoth.Json I think it is a good candidate for testing this core library idea.

The result would be:

  • Thoth.Fetch.Core : runtime independent library can be used in Fable or .Net code
  • Thoth.Fetch.Fable : Fable specific library
  • Thoth.Fetch.HttpClient (or another name) : .Net specific library

So people would referenced Thoth.Fetch.Core in their shared code and only when consuming their shared would they need to provide the runtime specific library.

This means that people would stop needing to use compiler directive to write cross runtime code.

Even if Thoth.Fetch codebase is simpler than Thoth.Json it can still be a challenge to adapt because they would not return exactly the same type.

  • Thoth.Fetch.Fable would return JS.Promise<'T>
  • Thoth.Fetch.HttpClient would return Async<'T>

MangelMaxime avatar Mar 05 '20 13:03 MangelMaxime

@shadaen If you are OK with reuse at the source-code level (as opposed to assembly) you could introduce a type alias and a set of functions to work with it. Here's how I did it to reuse the code that should work with task and async in one of my libs:

open System
[<AutoOpen>]
module internal AwaitableBuilder =
    open System.Threading.Tasks
#if TASKS
    open FSharp.Control.Tasks
    let awaitable = task
    type Awaitable<'r> = Task<'r>
    [<RequireQualifiedAccess>]
    module Awaitable =
        let inline result x = Task.FromResult x
        let inline awaitTask x = x
        let inline awaitUnitTask (x:Task) = x.ContinueWith<unit>(fun _ -> ())
        let inline awaitAsync x = Async.StartAsTask x
        let inline map f (x:Task<_>) = task { let! v = x in return f v }
        let inline bind f (x:Task<_>) = task { let! v = x in return! f v }
        let inline whenAll (xs:#seq<Task<'t>>) = Task.WhenAll<'t> (Array.ofSeq xs)
#else
    let awaitable = async
    type Awaitable<'r> = Async<'r>
    [<RequireQualifiedAccess>]
    module Awaitable =
        let inline result x = async.Return x
        let inline awaitTask x = Async.AwaitTask x
        let inline awaitUnitTask (x:Task) = Async.AwaitTask x
        let inline awaitAsync x = x
        let inline map f x = async { let! v = x in return f v }
        let inline bind f x = async { let! v = x in return! f v }
        let inline whenAll x = Async.Parallel x
#endif

then you just use Awaitable instead of one or the other

et1975:bulle_de_parole: il y a une heure have 2 projects that either define TASK or not and share the source code between them (modifié)

MangelMaxime avatar Mar 09 '20 15:03 MangelMaxime