Send requests to your GraphQL endpoint. See this live code demo
or the examples/
folder for some end-to-end examples.
The builder syntax is inspired by Luke Westby's
elm-http-builder package.
An internal request as it's built up. Once it's built up, send the
request with Graphql.Http.send
.
An Http Error. A Request can fail in a few ways:
BadUrl
means you did not provide a valid URL.Timeout
means it took too long to get a response.NetworkError
means the user turned off their wifi, went in a cave, etc.BadStatus
means you got a response back, but the status code indicates failure. The second argument in the payload is the response body.BadPayload
means you got a response back with a nice status code, but the body of the response was something unexpected. The String in this case is a debugging message that explains what went wrong with your JSON decoder or whatever.RawError parsedData HttpError
An alias for the default kind of Error. See the RawError
for the full
type.
Represents the two types of errors you can get, an Http error or a GraphQL error.
See the Graphql.Http.GraphqlError
module docs for more details.
Request
PipelinequeryRequest : String -> Graphql.SelectionSet.SelectionSet decodesTo Graphql.Operation.RootQuery -> Request decodesTo
Initialize a basic request from a Query. You can add on options with withHeader
,
withTimeout
, withCredentials
, and send it with Graphql.Http.send
.
mutationRequest : String -> Graphql.SelectionSet.SelectionSet decodesTo Graphql.Operation.RootMutation -> Request decodesTo
Initialize a basic request from a Mutation. You can add on options with withHeader
,
withTimeout
, withCredentials
, and send it with Graphql.Http.send
.
queryRequestWithHttpGet : String -> QueryRequestMethod -> Graphql.SelectionSet.SelectionSet decodesTo Graphql.Operation.RootQuery -> Request decodesTo
Exactly like queryRequest
, but with an option to use the HTTP GET request
method. You will probably want to use GetIfShortEnough
, which uses GET if the
full URL ends up being under 2000 characters, or POST otherwise, since some browsers
don't support URLs over a certain length.
GetIfShortEnough
will typically do what you need. If you must use GET no matter
what when hitting your endpoint, you can use AlwaysGet
.
queryRequest
always uses POST since some GraphQL API's don't support GET
requests (for example, the Github API assumes that you are doing an introspection
query if you make a GET request). But for semantic reasons, GET requests
are sometimes useful for sending GraphQL Query requests. That is, a GraphQL Query
does not perform side-effects on the server like a Mutation does, so a GET
indicates this and allows some servers to cache requests. See
this github thread from the Apollo project
for more details.
Union type to pass in to queryRequestWithHttpGet
. Only applies to queries.
Mutations don't accept this configuration option and will always use POST.
Request
OptionswithHeader : String -> String -> Request decodesTo -> Request decodesTo
Add a header.
makeRequest : Cmd Msg
makeRequest =
query
|> Graphql.Http.queryRequest "https://api.github.com/graphql"
|> Graphql.Http.withHeader "authorization" "Bearer <my token>"
|> Graphql.Http.send (RemoteData.fromResult >> GotResponse)
withTimeout : Basics.Float -> Request decodesTo -> Request decodesTo
Add a timeout.
withCredentials : Request decodesTo -> Request decodesTo
Set with credentials to true. See the XMLHttpRequest/withCredentials
docs
to understand exactly what happens.
Under the hood, this will use either Http.riskyRequest
or Http.riskyTask
.
withQueryParams : List ( String, String ) -> Request decodesTo -> Request decodesTo
Add query params. The values will be Uri encoded.
makeRequest : Cmd Msg
makeRequest =
query
|> Graphql.Http.queryRequest "https://api.github.com/graphql"
|> Graphql.Http.withQueryParams [ ( "version", "1.2.3" ) ]
|> Graphql.Http.send (RemoteData.fromResult >> GotResponse)
withOperationName : String -> Request decodesTo -> Request decodesTo
Set an operation name. This is a meaningful and explicit name for your operation, very helpful for debugging and server-side logging. See https://graphql.org/learn/queries/#operation-name
makeRequest : Cmd Msg
makeRequest =
query
|> Graphql.Http.queryRequest "https://api.github.com/graphql"
|> Graphql.Http.withOperationName "HeroNameAndFriends"
|> Graphql.Http.send (RemoteData.fromResult >> GotResponse)
Request
send : (Result (Error decodesTo) decodesTo -> msg) -> Request decodesTo -> Platform.Cmd.Cmd msg
Send the Graphql.Request
You can use it on its own, or with a library like
RemoteData.
import Graphql.Http
import Graphql.OptionalArgument exposing (OptionalArgument(..))
import RemoteData exposing (RemoteData)
type Msg
= GotResponse RemoteData (Graphql.Http.Error Response) Response
makeRequest : Cmd Msg
makeRequest =
query
|> Graphql.Http.queryRequest "https://elm-graphql.onrender.com/"
|> Graphql.Http.withHeader "authorization" "Bearer abcdefgh12345678"
-- If you're not using remote data, it's just
-- |> Graphql.Http.send GotResponse
-- With remote data, it's as below
|> Graphql.Http.send (RemoteData.fromResult >> GotResponse)
If any errors are present, you will get a GraphqlError
that includes the details.
GraphQL allows for partial data to be returned in the case of errors so you can
inspect the data returned in the GraphqlError
if you would like to try to recover
any data that made it through in the response.
sendWithTracker : String -> (Result (Error decodesTo) decodesTo -> msg) -> Request decodesTo -> Platform.Cmd.Cmd msg
Exactly like Graphql.Http.request
except it allows you to use the String
passed in as the tracker to track
and cancel
requests using the core Elm Http
package (see
the Http.request
docs)
toTask : Request decodesTo -> Task (Error decodesTo) decodesTo
Convert a Request to a Task. See Graphql.Http.send
for an example of
how to build up a Request.
Error
smapError : (a -> b) -> Error a -> Error b
Map the error data if it is ParsedData
.
discardParsedErrorData : Result (Error decodesTo) decodesTo -> Result (Error a) decodesTo
Useful when you don't want to deal with the recovered data if there is ParsedData
.
Just a shorthand for mapError
that will turn any ParsedData
into ()
.
This is helpful if you want to simplify your types, or if you are combining multiple results together and you need the error types to line up (but you don't care about recovering parsed data when there are GraphQL errors in the response).
In the examples below, notice the error type is now (Graphql.Http.Error ())
.
You can use this when you call Graphql.Http.send
like so:
import Graphql.Http
type Msg
= GotResponse (Result (Graphql.Http.Error ()) Response)
makeRequest =
query
|> Graphql.Http.queryRequest "http://elm-graphql.herokuapp.com"
|> Graphql.Http.send
(Graphql.Http.discardParsedErrorData
>> RemoteData.fromResult
>> GotResponse
)
Or if you are using the RemoteData package:
import Graphql.Http
import RemoteData exposing (RemoteData)
type Msg
= GotResponse (RemoteData (Graphql.Http.Error ()) Response)
makeRequest =
query
|> Graphql.Http.queryRequest "http://elm-graphql.herokuapp.com"
|> Graphql.Http.send
(Graphql.Http.discardParsedErrorData
>> RemoteData.fromResult
>> GotResponse
)
withSimpleHttpError : Result (Error parsedData) decodesTo -> Result (RawError parsedData Http.Error) decodesTo
Useful when you want to combine together an Http response with a Graphql request response.
-- this is just the type that our query decodes to
type alias Response =
{ hello : String }
type Msg
= GotResponse (RemoteData (Graphql.Http.RawError Response Http.Error) Response)
request =
query
|> Graphql.Http.queryRequest "https://some-graphql-api.com"
|> Graphql.Http.send
(Graphql.Http.withSimpleHttpError
>> RemoteData.fromResult
>> GotResponse
)
combinedResponses =
RemoteData.map2 Tuple.pair
model.graphqlResponse
(model.plainHttpResponse |> RemoteData.mapError Graphql.Http.HttpError)
There are 3 possible strategies to handle GraphQL errors.
parseableErrorAsSuccess
If there is a GraphQL error (and the data was
complete enough for the decoder to run successfully), pretend that there was
no error at all.parseableErrorAsSuccess : Result (Error decodesTo) decodesTo -> Result (Error ()) decodesTo
WARNING: When using this function you lose information. Make sure this is the approach you want before using this.
Treat responses with GraphQL errors as successful responses if the data can
be parsed. If you want to use the successfully decoded data without ignoring the
GraphQL error you can do a pattern match on the Graphql.Http.Error
type
(it contains PossiblyParsedData
which is either unparsed with a raw
Json.Decode.Value
or else it contains successfully decoded data).