Skip to content

Commit

Permalink
Experiment with an expectGraphQL
Browse files Browse the repository at this point in the history
  • Loading branch information
vodik committed Dec 2, 2018
1 parent 459395b commit 5b366db
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 40 deletions.
36 changes: 32 additions & 4 deletions src/GraphQL/Client/Http.elm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module GraphQL.Client.Http exposing (Error(..), RequestError, DocumentLocation,
import GraphQL.Client.Http.Util as Util
import GraphQL.Request.Builder as Builder
import Http
import Json.Decode
import Task exposing (Task)


Expand Down Expand Up @@ -75,9 +76,7 @@ send :
send options request toMsg =
let
expect =
Http.expectJson
(Result.mapError (Util.convertHttpError HttpError GraphQLError) >> toMsg)
(Util.dataDecoder (Builder.responseDataDecoder request))
expectGraphQL toMsg request

documentString =
Builder.requestBody request
Expand All @@ -89,5 +88,34 @@ send options request toMsg =
|> Http.request


expectGraphQL :
(Result Error result -> msg)
-> Builder.Request operationType result
-> Http.Expect msg
expectGraphQL toMsg request =
let
decoder =
Builder.responseDataDecoder request
in
Http.expectStringResponse toMsg <|
\response ->
case response of
Http.BadUrl_ url ->
Err (HttpError (Http.BadUrl url))

Http.Timeout_ ->
Err (HttpError Http.Timeout)

Http.NetworkError_ ->
Err (HttpError Http.NetworkError)

Http.BadStatus_ metadata body ->
Err (HttpError (Http.BadStatus metadata.statusCode))

Http.GoodStatus_ metadata body ->
case Json.Decode.decodeString decoder body of
Ok value ->
Ok value

-- |> Task.mapError (
Err err ->
Err (HttpError (Http.BadBody (Json.Decode.errorToString err)))
94 changes: 58 additions & 36 deletions src/GraphQL/Client/Http/Util.elm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module GraphQL.Client.Http.Util exposing (..)
module GraphQL.Client.Http.Util exposing (DocumentLocation, Error(..), RequestConfig, RequestError, RequestOptions, defaultRequestOptions, expectGraphQL, parameterizedUrl, postBody, postBodyJson, requestConfig)

import GraphQL.Response as Response
import Http
Expand All @@ -18,7 +18,7 @@ postBodyJson documentString variableValues =
|> Maybe.map (\obj -> [ ( "variables", obj ) ])
|> Maybe.withDefault []
in
Json.Encode.object ([ ( "query", documentValue ) ] ++ extraParams)
Json.Encode.object ([ ( "query", documentValue ) ] ++ extraParams)


postBody : String -> Maybe Json.Encode.Value -> Http.Body
Expand All @@ -32,6 +32,7 @@ parameterizedUrl url documentString variableValues =
firstParamPrefix =
if String.contains "?" url then
"&"

else
"?"

Expand All @@ -46,7 +47,7 @@ parameterizedUrl url documentString variableValues =
)
|> Maybe.withDefault ""
in
url ++ queryParam ++ variablesParam
url ++ queryParam ++ variablesParam


type alias RequestOptions =
Expand Down Expand Up @@ -81,7 +82,7 @@ type alias RequestConfig a =
, body : Http.Body
, expect : Http.Expect a
, timeout : Maybe Float
, tracker: Maybe String
, tracker : Maybe String
}


Expand All @@ -105,40 +106,61 @@ requestConfig requestOptions documentString expect variableValues =
( url, body ) =
if requestOptions.method == "GET" then
( parameterizedUrl requestOptions.url documentString variableValues, Http.emptyBody )

else
( requestOptions.url, postBody documentString variableValues )
in
{ method = requestOptions.method
, headers = requestOptions.headers
, url = url
, body = body
, expect = expect
, timeout = requestOptions.timeout
, tracker = Nothing
}


dataDecoder =
Json.Decode.field "data"


errorsResponseDecoder : Json.Decode.Decoder (List RequestError)
errorsResponseDecoder =
Json.Decode.field "errors" Response.errorsDecoder

{ method = requestOptions.method
, headers = requestOptions.headers
, url = url
, body = body
, expect = expect
, timeout = requestOptions.timeout
, tracker = Nothing
}

convertHttpError : (Http.Error -> err) -> (List RequestError -> err) -> Http.Error -> err
convertHttpError wrapHttpError wrapGraphQLError httpError =
let
handleErrorWithResponseBody responseBody =
responseBody
|> Json.Decode.decodeString errorsResponseDecoder
|> Result.map wrapGraphQLError
|> Result.withDefault (wrapHttpError httpError)
in
case httpError of
Http.BadBody body ->
handleErrorWithResponseBody body

_ ->
wrapHttpError httpError
expectGraphQL : (Result Error a -> msg) -> Json.Decode.Decoder a -> Http.Expect msg
expectGraphQL toMsg decoder =
Http.expectStringResponse toMsg <|
\response ->
case response of
Http.BadUrl_ url ->
Err (HttpError (Http.BadUrl url))

Http.Timeout_ ->
Err (HttpError Http.Timeout)

Http.NetworkError_ ->
Err (HttpError Http.NetworkError)

Http.BadStatus_ metadata body ->
Err (HttpError (Http.BadStatus metadata.statusCode))

Http.GoodStatus_ metadata body ->
case Json.Decode.decodeString decoder body of
Ok value ->
Ok value

Err err ->
Err (HttpError (Http.BadBody (Json.Decode.errorToString err)))



-- errorsResponseDecoder : Json.Decode.Decoder (List RequestError)
-- errorsResponseDecoder =
-- Json.Decode.field "errors" Response.errorsDecoder
-- convertHttpError : (Http.Error -> err) -> (List RequestError -> err) -> Http.Error -> err
-- convertHttpError wrapHttpError wrapGraphQLError httpError =
-- let
-- handleErrorWithResponseBody responseBody =
-- responseBody
-- |> Json.Decode.decodeString errorsResponseDecoder
-- |> Result.map wrapGraphQLError
-- |> Result.withDefault (wrapHttpError httpError)
-- in
-- case httpError of
-- Http.BadBody body ->
-- handleErrorWithResponseBody body
-- _ ->
-- wrapHttpError httpError

0 comments on commit 5b366db

Please sign in to comment.