# 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.4"}]
end
```
Optionally, add `import_deps: [:goblet]` to your .formatter.exs. This stops parentheses from being auto-injected around fragments.
## 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!()
|> Map.get("data")
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
# inline fragments work too
... on: "BestFriend" do
secretHandshake
end
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)
```