With the release of Elixir 1.13 it became possible to add plugins to the formatter. These plugins gives developers the option to hook into the Elixir formatter.
I’ve created an Elixir formatter plugin to Absinthe to format GraphQL documents. With the release of Absinthe 1.7 this is available for everyone to use.
To start, you’ll need Absinthe 1.7 or higher together with Elixir 1.13 or higher.
The Absinthe project comes with Absinthe.Formatter
, this is the default module you can add as a plugin. You can add it to your project as follows:
#.formatter.exs
[
plugins: [Absinthe.Formatter],
import_deps: [:ecto, :phoenix, :absinthe],
inputs: ["*.{ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{ex,exs}", "{lib,priv,test}/**/*.{gql,graphql}"]
]
This will format .graphql
and .gql
files. Note, currently it only works for executable GraphQL documents. Documents with schema definitions will not render well.
However, if you use GraphQL-strings in your modules, e.g. in tests or in client api operations we can format those as well.
E.g. you have a test file containing a GraphQL query:
#simple_test.exs
defmodule SimpleTest do
use ExUnit.Case
@query """
query test(
$token: String!) {
user { name }
}
"""
test "some query" do
assert {:ok, _} = Absinthe.run(@query, TestSchema)
end
end
By introducing a custom sigil we can format @query module attribute. It’s fairly simple. First we add a custom sigil, that does nothing but pass through the string. The below example adds the G
sigil.
defmodule GraphqlSigil do
@moduledoc """
Adds the ~G sigil
"""
def sigil_G(string, []), do: string
end
Next we add a custom formatter plugin matching on the custom G
sigil. The format/2 passes through to the original Absinthe.Formatter
defmodule GraphqlFormatter do
@behaviour Mix.Tasks.Format
def features(_opts) do
[sigils: [:G], extensions: []]
end
def format(contents, _opts \\ []) do
Absinthe.Formatter.format(contents)
end
end
Add the custom formatter to your .formatter.exs
#.formatter.exs
[
plugins: [GraphqlFormatter],
#...
]
Import and use the sigil in your testfile.
defmodule SimpleTest do
use ExUnit.Case
import GraphqlSigil
@query ~G"""
query test($token: String!) {
user {
name
}
}
"""
end
Now you can run mix format
and it will format the strings with the G
sigil. You may need to run mix compile
before it works.
Photo by Viktor Jakovlev on Unsplash