Elixir, Phoenix, and GraphQL(Absinthe)
Long time ago, I play Elixir and write down an article about Phoenix. Time has passed, now I'm really working with Elixir XD. Today, I want to show how to set up a GraphQL server with Elixir/Phoenix stack, we will need a library called Absinthe. This article requires you already to know how to create Phoenix project, now, let's start.
After you have a Phoenix project, we need to add dependencies in
mix.exs first:
defp deps do
[
# ...
# GraphQL
{:absinthe, "~> 1.4"},
{:absinthe_plug, "~> 1.4"}
]
end
Then run mix deps.get. Before we create GraphQL schema, we need some
data to interact with, you can run
mix phx.gen.context Log Events events event_type:string message:string payload:text
to get a model then run mix ecto.migrate to set up Database.
1. Query
Imagine the schema:
{
events {
id
event_type
message
payload
inserted_at
updated_at
}
}
We will create lib/xxx_web/schema/event.ex with the following content:
defmodule XxxWeb.Schema.DataTypes do
use Absinthe.Schema.Notation
object :event do
field :id, :id
field :event_type, :string
field :message, :string
field :payload, :string
end
end
then create lib/xxx_web/schema.ex with the following content:
defmodule XxxWeb.Schema do
use Absinthe.Schema
import_types XxxWeb.Schema.DataTypes
query do
@desc "Get a list of events"
field :events, list_of(:event) do
resolve fn _parent, _args, _resolution ->
{:ok, Xxx.Log.list_events()}
end
end
end
end
In the project xxx, there will have a file lib/xxx_web/router.ex,
now we have to modify it, delete the following code:
scope "/" do pipe_through :browser # Use the default browser stack get "/", PageController, :index end
then add the following:
scope "/api" do pipe_through :api forward "/graphiql", Absinthe.Plug.GraphiQL, schema: XxxWeb.Schema end
Finally, we can test it out, run iex mix -S phx.server to start the
server. Now, connect to http://localhost:4000/api/graphiql with the
browser, it will show a GraphQL playground you can play with it.
2. Mutation
We would like to create some data, how to do this? We still modify
lib/xxx_web/schema.ex
defmodule XxxWeb.Schema do
# ...
mutation do
@desc "Create a new event"
field :create_event, :string do
arg(:event_type, non_null(:string))
arg(:message, :string)
arg(:payload, :string)
resolve fn _parent, params, _resolution ->
case Xxx.Log.create_event(params) do
{:ok, _} -> {:ok, "event created"}
{:error, changeset} -> {:error, inspect(changeset.errors)}
end
end
end
end
end
Now you can use the following mutation to create an event:
mutation {
createEvent(event_type: "Test", message: "Hello")
}
3. Summary
Now we know how to create queries and mutation with Absinthe, we don't cover how to add middleware, how to write unit test for our code. You will be able to get more information about those uncovered in document of Absinthe, have a nice day.