absinthe v0.2.2 Absinthe.Schema behaviour

Define a GraphQL schema.

Basic Usage

To define a schema, use Absinthe.Schema within a module. This marks your module as adhering to the Absinthe.Schema behaviour, and sets up some macros and utility functions for your use:

defmodule App.Schema do

  use Absinthe.Schema

  # ... define it here!

end

Now, define a query function (and optionally, mutation and subscription) functions. These should return the root objects for each of those operations.

We’ll define a query that has one field, item, to support querying for an item record by its ID:

# Just for the example. You're probably using Ecto or
# something much more interesting than a module attribute-based
# database!
@fake_db %{
  "foo" => %{id: "foo", name: "Foo", value: 4},
  "bar" => %{id: "bar", name: "Bar", value: 5}
}

def query do
  %Absinthe.Type.Object{
    fields: fields(
      item: [
        type: :item,
        description: "Get an item by ID",
        args: args(
          id: [type: :id, description: "The ID of the item"]
        ),
        resolve: fn %{id: id}, _ ->
          {:ok, Map.get(@fake_db, id)}
        end
      ]
    )
  }
end

We use Absinthe.Type.Definitions.fields/1 and Absinthe.Type.Definitions.args/1 here, available automatically because of the use Absinthe.Schema at the top of our module. These are convenience functions that ease compact, readable definitions for fields and arguments.

For more information on object types (especially how the resolve function works above), see Absinthe.Type.Object.

You may also notice we’ve declared that the resolved value of the field to be of type: :item. We now need to define exactly what an :item is, and what fields it contains.

Thankfully another Absinthe.Type.Definitions utility can be used to do this easily, and inside our schema module. We just need to set the @absinthe module attribute before a function that returns an object type:

@absinthe :type
def item do
  %Absinthe.Type.Object{
    description: "A valuable item",
    fields: fields(
      id: [type: :id],
      name: [type: :string, description: "The item's name"],
      value: [type: :integer, description: "Recently appraised value"]
    )
  }
end

(You can read more about building custom types and the available convenience functions in Absinthe.Type.Definitions — and check out Absinthe.Type.Scalar, where the built-in types like :integer, :id, and :string are defined.)

We can also load types from other modules using the :type_modules option in our use Absinthe.Schema, eg:

defmodule App.Schema do

  use Absinthe.Schema, type_modules: [App.Schema.Scalars, App.Schema.Objects]

  # ... schema definition

end

Our :item type above could then move into App.Schema.Objects:

defmodule App.Schema.Objects do

  use Absinthe.Type.Definitions

  @absinthe :type
  def item do
    # ... type definition
  end

  # ... other objects!

end

Our schema is now ready to be executed (using, eg, Absinthe.run/2 and friends).

Summary

Types

t()

A struct containing the defined schema details

Functions

Verify that a schema is correctly formed

Callbacks

(Optional) Define the mutation root type

(Required) Define the query root type

(Optional) Define the subscription root type

Types

t :: %{query: Absinthe.Type.Object.t, mutation: nil | Absinthe.Type.Object.t, subscription: nil | Absinthe.Type.Object.t, type_modules: [atom], types: Absinthe.Schema.Types.typemap_t, errors: [binary]}

A struct containing the defined schema details.

Don’t create these structs yourself. Just define the necessary Absinthe.Schema callbacks and use schema/0

Functions

verify(name)

Specs

verify(atom | t) :: {:ok, t} | {:error, [binary]}

Verify that a schema is correctly formed

Examples

{:ok, schema} is returned if the schema is free of errors:

{:ok, schema} = Absinthe.Schema.verify(App.GoodSchema)

Otherwise the errors are returned in a tuple:

{:error, errors} = Absinthe.Schema.verify(App.BadSchema)

Callbacks

mutation()

Specs

mutation :: nil | Absinthe.Type.Object.t

(Optional) Define the mutation root type.

Should be an Absinthe.Type.Object struct.

query()

Specs

(Required) Define the query root type.

Should be an Absinthe.Type.Object struct.

subscription()

Specs

subscription :: nil | Absinthe.Type.Object.t

(Optional) Define the subscription root type.

Should be an Absinthe.Type.Object struct.