absinthe v1.1.5 Absinthe.Schema
Define a GraphQL schema.
See also Absinthe.Schema.Notation
for a reference of the macros imported by
this module available to build types for your 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
(and optionally, mutation
and subscription
).
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}
}
query do
@desc "Get an item by ID"
field :item, :item do
@desc "The ID of the item"
arg :id, type: :id
resolve fn %{id: id}, _ ->
{:ok, Map.get(@fake_db, id)}
end
end
end
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.
@desc "A valuable Item"
object :item do
field :id, :id
@desc "The item's name"
field :name, :string,
field :value, :integer, description: "Recently appraised value"
end
We can also load types from other modules using the import_types
macro:
defmodule App.Schema do
use Absinthe.Schema
import_types App.Schema.Scalars
import_types App.Schema.Objects
# ... schema definition
end
Our :item
type above could then move into App.Schema.Objects
:
defmodule App.Schema.Objects do
use Absinthe.Scheme.Notation
object :item do
# ... type definition
end
# ... other objects!
end
Default Resolver
By default, if a resolve
function is not provided for a field, Absinthe
will attempt to extract the value of the field using Map.get/2
with the
(atom) name of the field.
You can change this behavior by setting your own custom default resolve
function in your schema. For example, given we have a field, name
:
field :name, :string
And we’re trying to extract values from a horrible backend API that gives us maps with uppercase (!) string keys:
%{"NAME" => "A name"}
Here’s how we could set our custom resolver to expect those keys:
default_resolve fn
_, %{source: source, definition: %{name: name}} when is_map(source) ->
{:ok, Map.get(source, String.upcase(name))}
_, _ ->
{:ok, nil}
end
Note this will now act as the default resolver for all fields in our schema
without their own resolve
function.
Summary
Functions
List all directives on a schema
List all implementors of an interface on a schema
Lookup a directive
Lookup a type by name, identifier, or by unwrapping
List all types on a schema
Macros
Defines a custom default resolve function for the schema
Defines a root Mutation object
Defines a root Mutation object
Defines a root Query object
Defines a root Query object
Defines a root Subscription object
Defines a root Subscription object
Types
t :: atom
A module defining a schema.
Functions
Specs
directives(t) :: [Absinthe.Type.Directive.t]
List all directives on a schema
Specs
implementors(t, atom) :: [Absinthe.Type.Object.t]
List all implementors of an interface on a schema
Specs
lookup_directive(t, atom | binary) ::
Absinthe.Type.Directive.t |
nil
Lookup a directive.
Specs
lookup_type(atom, Absinthe.Type.wrapping_t | Absinthe.Type.t | Absinthe.Type.identifier_t, Keyword.t) ::
Absinthe.Type.t |
nil
Lookup a type by name, identifier, or by unwrapping.