aboutsummaryrefslogtreecommitdiff
path: root/docs/tutorial
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorial')
-rw-r--r--docs/tutorial/tutorial.lhs98
1 files changed, 38 insertions, 60 deletions
diff --git a/docs/tutorial/tutorial.lhs b/docs/tutorial/tutorial.lhs
index 13afb81..dc44c1e 100644
--- a/docs/tutorial/tutorial.lhs
+++ b/docs/tutorial/tutorial.lhs
@@ -5,11 +5,13 @@ title: GraphQL Haskell Tutorial
== Getting started ==
-Welcome to graphql-haskell!
+Welcome to GraphQL!
-We have written a small tutorial to help you (and ourselves) understand the graphql package.
+We have written a small tutorial to help you (and ourselves) understand the
+graphql package.
-Since this file is a literate haskell file, we start by importing some dependencies.
+Since this file is a literate haskell file, we start by importing some
+dependencies.
> {-# LANGUAGE OverloadedStrings #-}
> module Main where
@@ -23,75 +25,76 @@ Since this file is a literate haskell file, we start by importing some dependenc
> import Data.Time (getCurrentTime)
>
> import Language.GraphQL
-> import Language.GraphQL.Trans
> import Language.GraphQL.Type
> import qualified Language.GraphQL.Type.Out as Out
>
> import Prelude hiding (putStrLn)
+
=== First example ===
-Now, as our first example, we are going to look at the
-example from [graphql.js](https://github.com/graphql/graphql-js).
+Now, as our first example, we are going to look at the example from
+[graphql.js](https://github.com/graphql/graphql-js).
First we build a GraphQL schema.
> schema1 :: Schema IO
-> schema1 = Schema queryType Nothing
+> schema1 = Schema
+> { query = queryType , mutation = Nothing , subscription = Nothing }
>
> queryType :: ObjectType IO
> queryType = ObjectType "Query" Nothing []
> $ HashMap.singleton "hello"
-> $ Out.Resolver helloField hello
+> $ ValueResolver helloField hello
>
> helloField :: Field IO
> helloField = Field Nothing (Out.NamedScalarType string) mempty
>
-> hello :: ActionT IO Value
+> hello :: Resolve IO
> hello = pure $ String "it's me"
-This defines a simple schema with one type and one field, that resolves to a fixed value.
+This defines a simple schema with one type and one field, that resolves to a
+fixed value.
Next we define our query.
> query1 :: Text
> query1 = "{ hello }"
-
To run the query, we call the `graphql` with the schema and the query.
> main1 :: IO ()
-> main1 = graphql schema1 query1 >>= putStrLn . encode
+> main1 = graphql schema1 query1
+> >>= either (const $ pure ()) (putStrLn . encode)
-This runs the query by fetching the one field defined,
-returning
+This runs the query by fetching the one field defined, returning
```{"data" : {"hello":"it's me"}}```
-
=== Monadic actions ===
For this example, we're going to be using time.
> schema2 :: Schema IO
-> schema2 = Schema queryType2 Nothing
+> schema2 = Schema
+> { query = queryType2, mutation = Nothing, subscription = Nothing }
>
> queryType2 :: ObjectType IO
> queryType2 = ObjectType "Query" Nothing []
> $ HashMap.singleton "time"
-> $ Out.Resolver timeField time
+> $ ValueResolver timeField time
>
> timeField :: Field IO
> timeField = Field Nothing (Out.NamedScalarType string) mempty
>
-> time :: ActionT IO Value
+> time :: Resolve IO
> time = do
> t <- liftIO getCurrentTime
> pure $ String $ Text.pack $ show t
-This defines a simple schema with one type and one field,
-which resolves to the current time.
+This defines a simple schema with one type and one field, which resolves to the
+current time.
Next we define our query.
@@ -99,76 +102,51 @@ Next we define our query.
> query2 = "{ time }"
>
> main2 :: IO ()
-> main2 = graphql schema2 query2 >>= putStrLn . encode
+> main2 = graphql schema2 query2
+> >>= either (const $ pure ()) (putStrLn . encode)
This runs the query, returning the current time
```{"data": {"time":"2016-03-08 23:28:14.546899 UTC"}}```
-=== Errors ===
-
-Errors are handled according to the spec,
-with fields that cause erros being resolved to `null`,
-and an error being added to the error list.
-
-An example of this is the following query:
-
-> queryShouldFail :: Text
-> queryShouldFail = "{ boyhowdy }"
-
-Since there is no `boyhowdy` field in our schema, it will not resolve,
-and the query will fail, as we can see in the following example.
-
-> mainShouldFail :: IO ()
-> mainShouldFail = do
-> success <- graphql schema1 query1
-> putStrLn $ encode success
-> putStrLn "This will fail"
-> failure <- graphql schema1 queryShouldFail
-> putStrLn $ encode failure
->
-
-This outputs:
-
-```
-{"data": {"hello": "it's me"}}
-This will fail
-{"data": {"boyhowdy": null}, "errors":[{"message": "the field boyhowdy did not resolve."}]}
-```
-
=== Combining resolvers ===
Now that we have two resolvers, we can define a schema which uses them both.
> schema3 :: Schema IO
-> schema3 = Schema queryType3 Nothing
+> schema3 = Schema
+> { query = queryType3, mutation = Nothing, subscription = Nothing }
>
> queryType3 :: ObjectType IO
> queryType3 = ObjectType "Query" Nothing [] $ HashMap.fromList
-> [ ("hello", Out.Resolver helloField hello)
-> , ("time", Out.Resolver timeField time)
+> [ ("hello", ValueResolver helloField hello)
+> , ("time", ValueResolver timeField time)
> ]
>
> query3 :: Text
> query3 = "query timeAndHello { time hello }"
>
> main3 :: IO ()
-> main3 = graphql schema3 query3 >>= putStrLn . encode
+> main3 = graphql schema3 query3
+> >>= either (const $ pure ()) (putStrLn . encode)
This queries for both time and hello, returning
```{ "data": {"hello":"it's me","time":"2016-03-08 23:29:11.62108 UTC"}}```
-Notice that we can name our queries, as we did with `timeAndHello`. Since we have only been using single queries, we can use the shorthand `{ time hello}`, as we have been doing in the previous examples.
+Notice that we can name our queries, as we did with `timeAndHello`. Since we
+have only been using single queries, we can use the shorthand `{ time hello }`,
+as we have been doing in the previous examples.
In GraphQL there can only be one operation per query.
== Further examples ==
-More examples on queries and a more complex schema can be found in the test directory,
-in the [Test.StarWars](../../tests/Test/StarWars) module. This includes a more complex schema, and more complex queries.
+More examples on queries and a more complex schema can be found in the test
+directory, in the [Test.StarWars](../../tests/Test/StarWars) module. This
+includes a more complex schema, and more complex queries.
> main :: IO ()
-> main = main1 >> main2 >> mainShouldFail >> main3
+> main = main1 >> main2 >> main3