john-kelly / elm-postgrest

Make PostgREST requests in Elm

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Addition of a Request "send"

john-kelly opened this issue · comments

The essence of this change is that I'd like to have a function with the same API as Http.send from elm/http:

https://package.elm-lang.org/packages/elm/http/latest/Http#send

send : (Result Error a -> msg) -> Request a -> Cmd msg

Right now, this is not possible because the URL (among other options) is not a part of the Rest.Request a value. In the APIs current state, we pass those options via the toHttpRequest function:

toHttpRequest : { timeout : Maybe Float, token : Maybe String, url : String } -> Request a -> Http.Request a

My idea is to pass these options as a part of each CRUD function, like so:

readMany :
    { baseUrl : String
    , token : Maybe String
    , timeout : Maybe Float
    , schema : Schema id attributes
    , select : Selection attributes a
    , where_ : Condition attributes
    , order : List (Order attributes)
    , limit : Maybe Int
    , offset : Maybe Int
    }
    -> Request (List a)

or

readMany :
    { baseUrl : String
    , token : Maybe String
    , timeout : Maybe Float
    } -> 
    {
    , schema : Schema id attributes
    , select : Selection attributes a
    , where_ : Condition attributes
    , order : List (Order attributes)
    , limit : Maybe Int
    , offset : Maybe Int
    }
    -> Request (List a)

As an alternative solution, we could just pass these options to the proposed send function, like so:

type alias Options =     
    { baseUrl : String
    , token : Maybe String
    , timeout : Maybe Float
    }

send : Options -> (Result Error a -> msg) -> Request a -> Cmd msg

I'm not yet sure what makes the most sense, however, I wanted to document some thoughts.

Things like: the order of the options, whether it's a record, if we provide a "default" value, etc all depend on how/where people are using these functions + what things are likely to be partially applied.

So Rest.send will be:

send : (Result Http.Error a -> msg) -> Request a -> Cmd msg
send =
    Http.send

What is your reason for wanting it?

send would be:

send : (Result Rest.Error a -> msg) -> Rest.Request a -> Cmd msg

as opposed what you @russelldavies wrote above:

send : (Result Http.Error a -> msg) -> Http.Request a -> Cmd msg

the difference being Http.* vs Rest.*

My reason for wanting to add it is to make the API closer to that of HTTP + have a nice and easy taskless way to send things. We'd still have a toHttp and/or toTask for lower level stuff.

Ah okay, that makes sense. And you mentioned the lower level functions so all good (as I often use Http.toTask).

Anyway, I prefer option 3. It is the least cumbersome and most flexible because you can change request options at the last moment. Option 2 with reversed parameter order is also ok as you can then curry it.

As a point of reference, this is what I've done to accommodate the new API changes in Http v2:

httpRequest : { baseUrl : String, token : Maybe String, toMsg : Result Http.Error a -> msg, timeout : Maybe Float } -> Request msg a -> Cmd msg

httpTask : { baseUrl : String, token : Maybe String, timeout : Maybe Float } -> Request msg a -> Task Http.Error a