blog-samples icon indicating copy to clipboard operation
blog-samples copied to clipboard

New version of HttpFs affects example of the book

Open mariomeyrelles opened this issue 8 years ago • 3 comments

Good morning Tamizhvendan,

I have been following the examples of the book and thinks have changed a little bit since the edition of the book. Now, HttpFs using Hopac.dll to do its inner workings. This change impacts a little bit on how to make things work. Now there are more abstractions to consider like "Alt", "Job" and so on.

I changed a little bit your example of get request async in order to make thinks work again. In fact, it works but I'm not sure if this is the best way:

let getResponseAsync url = 
    async { 
        let req = Request.create Get (Uri url) |> Request.setHeader (UserAgent "FsharpTest")
        return job { 
                   let! response = getResponse req
                   let output = 
                       match response.statusCode with
                       | 200 -> 
                           let b = Response.readBodyAsString response |> run
                           Ok b
                       | _ -> Error response.statusCode
                   return output
               }
               |> run
    }

let asyncResponseToObservable = getResponseAsync >> Observable.ofAsync

Do you agree? Do you have a better solution?

Kind regards from Brazil.

mariomeyrelles avatar Dec 28 '16 11:12 mariomeyrelles

I was not aware of this @mariomeyrelles and I haven't used the recent version of httpfs. Will check and revert back.

Thanks for the suggestion :)

tamizhvendan avatar Jan 02 '17 05:01 tamizhvendan

Hello @tamizhvendan

I think the correct approach to use the new version of HttpFs is like this:


type ApiHttpResponse = 
    | Ok of body : string
    | Error of statusCode : int
    | Exception of e : exn
    
/// Get request Async.
let getAsync urlStr : Async<ApiHttpResponse> = 
    let resp =
        Request.create Get (Uri urlStr)
        |> getResponse
    
    resp
    |> Alt.afterJob (fun resp -> 
        match resp.statusCode with
        | x when x < 300 ->
            resp
            |> Response.readBodyAsString
            |> Job.map Ok
        | x -> Error resp.statusCode |> Job.result)
    |> Alt.toAsync 


/// Post request async, após a ajuda do @haf: https://github.com/haf/Http.fs/issues/117#event-914147149
let postAsync urlStr bodyStr : Async<ApiHttpResponse> = 
    let resp = 
        Request.create Post (Uri urlStr)
        |> Request.bodyString bodyStr
        |> getResponse
    resp
    |> Alt.afterJob (fun resp -> 
           // if we don't cancel the request, let's read the body in full
           match resp.statusCode with
           | x when x < 300 -> 
               resp
               |> Response.readBodyAsString
               |> Job.map Ok
           | x -> Error resp.statusCode |> Job.result)
    |> Alt.toAsync

mariomeyrelles avatar Jan 13 '17 12:01 mariomeyrelles

Thanks, @mariomeyrelles. I will update this in the next update of the book.

tamizhvendan avatar Jan 20 '17 06:01 tamizhvendan