README.md

# Goblet

> Something to help you consume that sweet, sweet absinthe.

A GraphQL client library that formats and sends queries and mutations to your GraphQL server while also validating those queries and mutations against a schema at compile time. ([documentation](https://hexdocs.pm/goblet))

## Installation

The package can be installed by adding `goblet` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [{:goblet, "~> 0.1.3"}]
end
```

## Basic Usage

```elixir
defmodule MyGoblet do
  use Goblet, from: "./path/to/schema.json"

  def process(query, _ctx) do
    HTTPoison.post!("https://api.myserver.example/graphql", Jason.encode!(query), [
      {"Content-Type", "application/json"},
      {"Authorization", "Bearer TOKEN_GOES_HERE"}
    ])
    |> Map.get(:body)
    |> Jason.decode!()
  end
end

defmodule Queries do
  use MyGoblet

  query "FetchUser" do
    # Supports variable pinning with ^
    user(id: ^id) do
      id
      name

      friends(first: 3) do
        id
        name
        profilePic
      end

      # Alias fields using the @as directive
      @as "moreFriends"
      friends(first: 15) do
        id
        name
      end
    end
  end
end

# Invoke queries by their elixir-ized names: FetchUser -> fetch_user
Queries.fetch_user(%{id: "abc"})
# %{
#   "operationName" => "FetchUser",
#   "query" =>
#     "query FetchUser($id: ID!) {user(id: $id) {id name friends(first: 3){id name profilePic} moreFriends:friends(first:15){id name}}}",
#   "variables" => %{id: "abc"}
# }

Queries.fetch_user(%{id: "abc"}, ctx)
# formats the query like above and then passes it, along with ctx, into your process function
```

## Fetching your schema

To validate your queries, Goblet needs to be passed a schema.json file which represents the GraphQL schema of the server you are making requests against. You can fetch your schema by sending the query generated by `Goblet.Introspection.query` to your server. Make sure that the json file you end up with has a `__schema` key at the root. Here's an example of how one might use it:

```elixir
query = Goblet.Introspection.query()

schema =
  HTTPoison.post!("https://api.myserver.example/graphql", Jason.encode!(query), [
    {"Content-Type", "application/json"},
    {"Authorization", "Bearer TOKEN_GOES_HERE"}
  ])
  |> Map.get(:body)
  |> Jason.decode!()
  |> Map.get("data")
  |> Jason.encode!()

File.write!("./schema.json", schema)
```