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)
The package can be installed by adding goblet
to your list of dependencies in mix.exs
:
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.
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
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:
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)