import SEO from "../components/seo";

<SEO title="Morpheus GraphQL Client" />

## Morpheus GraphQL Client

The Morpheus GQL client enables the use of GQL queries and mutations on HTTP servers
and also the subscription of specific topics to GQL subscriptions using websockets.

## GQL Query/Mutation on HTTP server

Suppose we have the following GQL schema from which we want to retrieve information about the hero Poseidon.

```graphql
type Deity {
  name: String!
  power: String
  realm: Realm!
  bornAt: City
}

enum Realm {
  Sky
  Sea
  Underworld
}

type Query {
  deity(name: String!, realm: Realm): Deity!
}
```

we should start with `declareGlobalTypes` to declare haskell type for `Realm`

```hs
declareGlobalTypes "assets/mythology.gql"
```

now we can declare haskell type for qurey `GetHero`.

```hs
declareLocalTypesInline
  "assets/mythology.gql"
  [raw|
    query GetHero ($name: String!, realm: Sea)
      {
        deity (name:$name) {
          name
          power
        }
      }
  |]
```

at the last stage, we can define Morpheus HTTP client with URL and custom headers which can be used to fetch Hero.

```hs
client :: GQLClient
client = "http://localhost:3000" `withHeaders` [("custom-header", "custom-value")]

fetchHero :: IO (ResponseStream GetHero)
fetchHero = request client GetHeroArgs {name = "poseidon"}
```

## GQL Subscription with WS server

Suppose we have the following GQL schema, from which we want to subscribe information about the new users.

```graphql
type User {
  name: String!
  email: String!
}

type Query {
  user: User!
}

type Subscription {
  newUser: User!
}
```

as in the example above, we will start with the declaration of global and subscription types

```hs
declareGlobalTypes "assets/users.gql"

declareLocalTypesInline
  "assets/users.gql"
  [raw|
    subscription NewUsers
      {
         newUser {
           name
           email
        }
      }
  |]
```

as in previous example we will define client with websockets URL and use it.
However, now it results stream of `NewUsers` instead of the single response. To print these results each time
we receive a new user, we can use the function `forEach`.

```hs
client :: GQLClient
client = "ws://localhost:3000"

newUsers :: IO (ResponseStream NewUsers)
newUsers = request client ()

subscribeUSers :: IO ()
subscribeUSers = newUsers >>= forEach print
```
