View Source Absinthe.Schema.Notation (absinthe v1.7.5)

Provides a set of macros to use when creating a schema. Especially useful when moving definitions out into a different module than the schema itself.

example

Example

defmodule MyAppWeb.Schema.Types do
  use Absinthe.Schema.Notation

  object :item do
    field :id, :id
    field :name, :string
    field :status, :status_enum
  end

  enum :status_enum do
    value :current
    value :discontinued
  end

  # ...

end

Link to this section Summary

Functions

Add an argument.

Add an argument.

Set the complexity of a field

Configure a subscription field.

Mark a field as deprecated

Defines a description

Defines or applies a directive

Defines an enum type

Defines an enum type

Define the expansion for a directive

Extend a GraphQL type.

Defines a GraphQL field

Defines a GraphQL field

Defines a GraphQL field.

Import directives from another module

Import fields from another object

Import types defined using the Schema Definition Language (SDL).

Import type_extensions from another module

Import types from another module

Declare an implemented interface for an object.

Define an interface type.

Declare implemented interfaces for an object.

Placement

Allowed under: object

Marks a type reference as a list of the given type

Defines list of metadata's key/value pair for a custom type.

Defines a metadata key/value pair for a custom type.

Marks a type reference as non null

Declare a directive as operating an a AST node type

Defines a parse function for a scalar type

Set whether the directive can be applied multiple times an entity.

Defines a resolve function for a field

Define a type resolver for a union or interface.

Defines a scalar type

Define a scalar type

Declare a schema

Defines a serialization function for a scalar type

Sets triggers for a subscription, and configures which topics to publish to when that subscription is triggered.

Defines the types possible under a union type

Defines a value possible under an enum type

Link to this section Types

@type import_sdl_option() :: {:path, String.t() | Macro.t()}

Link to this section Functions

Link to this macro

arg(identifier, attrs)

View Source (macro)

Add an argument.

See arg/3

Link to this macro

arg(identifier, type, attrs)

View Source (macro)

Add an argument.

placement

Placement

Allowed under: directive field

examples

Examples

field do
  arg :size, :integer
  arg :name, non_null(:string), description: "The desired name"
  arg :public, :boolean, default_value: true
end
Link to this macro

complexity(func_ast)

View Source (macro)

Set the complexity of a field

For a field, the first argument to the function you supply to complexity/1 is the user arguments -- just as a field's resolver can use user arguments to resolve its value, the complexity function that you provide can use the same arguments to calculate the field's complexity.

The second argument passed to your complexity function is the sum of all the complexity scores of all the fields nested below the current field.

An optional third argument is passed an Absinthe.Complexity struct, which includes information like the context passed to Absinthe.run/3.

placement

Placement

Allowed under: field

examples

Examples

query do
  field :people, list_of(:person) do
    arg :limit, :integer, default_value: 10
    complexity fn %{limit: limit}, child_complexity ->
      # set complexity based on maximum number of items in the list and
      # complexity of a child.
      limit * child_complexity
    end
  end
end
Link to this macro

config(config_fun)

View Source (macro)

Configure a subscription field.

The first argument to the config function is the field arguments passed in the subscription. The second argument is an Absinthe.Resolution struct, which includes information like the context and other execution data.

placement

Placement

Allowed under: field

examples

Examples

config fn args, %{context: context} ->
  if authorized?(context) do
    {:ok, topic: args.client_id}
  else
    {:error, "unauthorized"}
  end
end

Alternatively can provide a list of topics:

config fn _, _ ->
  {:ok, topic: ["topic_one", "topic_two", "topic_three"]}
end

Using context_id option to allow de-duplication of updates:

config fn _, %{context: context} ->
  if authorized?(context) do
    {:ok, topic: "topic_one", context_id: "authorized"}
  else
    {:ok, topic: "topic_one", context_id: "not-authorized"}
  end
end

See Absinthe.Schema.subscription/1 for details

Link to this macro

deprecate(msg \\ nil)

View Source (macro)

Mark a field as deprecated

In most cases you can simply pass the deprecate: "message" attribute. However when using the block form of a field it can be nice to also use this macro.

placement

Placement

Allowed under: field

examples

Examples

field :foo, :string do
  deprecate "Foo will no longer be supported"
end

This is how to deprecate other things

field :foo, :string do
  arg :bar, :integer, deprecate: "This isn't supported either"
end

enum :colors do
  value :red
  value :blue, deprecate: "This isn't supported"
end
Link to this macro

description(text)

View Source (macro)

Defines a description

This macro adds a description to any other macro which takes a block.

Note that you can also specify a description by using @desc above any item that can take a description attribute.

placement

Placement

Allowed under any block. Not allowed to be top level

Link to this macro

directive(identifier)

View Source (macro)
Link to this macro

directive(identifier, attrs)

View Source (macro)
Link to this macro

directive(identifier, attrs, list)

View Source (macro)

Defines or applies a directive

defining-a-directive

Defining a directive

placement

Placement

Top level in module or in an extend block.

examples

Examples

directive :mydirective do
  arg :if, non_null(:boolean), description: "Skipped when true."
  on [:field, :fragment_spread, :inline_fragment]

  expand fn
    %{if: true}, node ->
      Blueprint.put_flag(node, :skip, __MODULE__)
    _, node ->
      node
  end
end

applying-a-type-system-directive

Applying a type system directive

Directives can be applied in your schema. E.g. by default the @deprecated directive is available to be applied to fields and enum values.

You can define your own type system directives. See Absinthe.Schema.Prototype for more information.

placement-1

Placement

Allowed under: arg enum field input_object interface object scalar schema_declaration union value

examples-1

Examples

When you have a type system directive named :feature it can be applied as follows:

object :post do
  directive :feature, name: ":object"

  field :name, :string do
    deprecate "Bye"
  end
end

scalar :sweet_scalar do
  directive :feature, name: ":scalar"
  parse &Function.identity/1
  serialize &Function.identity/1
end
Link to this macro

enum(identifier, attrs)

View Source (macro)

Defines an enum type

See enum/3

Link to this macro

enum(identifier, attrs, list)

View Source (macro)

Defines an enum type

placement

Placement

Top level in module or in an extend block.

examples

Examples

Handling RED, GREEN, BLUE values from the query document:

enum :color do
  value :red
  value :green
  value :blue
end

A given query document might look like:

{
  foo(color: RED)
}

Internally you would get an argument in elixir that looks like:

%{color: :red}

If your return value is an enum, it will get serialized out as:

{"color": "RED"}

You can provide custom value mappings. Here we use r, g, b values:

enum :color do
  value :red, as: "r"
  value :green, as: "g"
  value :blue, as: "b"
end
Link to this macro

expand(func_ast)

View Source (macro)

Define the expansion for a directive

placement

Placement

Allowed under: directive

Link to this macro

extend(arg, list)

View Source (macro)
Link to this macro

extend(arg, attrs, list)

View Source (macro)

Extend a GraphQL type.

Extend an existing type with additional fields, values, types and interfaces.

placement

Placement

Top level in module.

examples

Examples

object :user do
  field :name, :string
  # ...
end

extend object :user do
    field :nick_name, :string
    # ...
  end
end
Link to this macro

field(identifier, attrs)

View Source (macro)

Defines a GraphQL field

See field/4

Link to this macro

field(identifier, attrs, attrs)

View Source (macro)

Defines a GraphQL field

See field/4

Link to this macro

field(identifier, type, attrs, list)

View Source (macro)

Defines a GraphQL field.

placement

Placement

Allowed under: input_object interface object schema_declaration

query, mutation, and subscription are all objects under the covers, and thus you'll find field definitions under those as well.

examples

Examples

field :id, :id
field :age, :integer, description: "How old the item is"
field :name, :string do
  description "The name of the item"
end
field :location, type: :location
Link to this function

grab_functions(origin, type, identifier, attrs)

View Source
Link to this function

handle_arg_attrs(identifier, type, raw_attrs)

View Source
Link to this function

handle_enum_value_attrs(identifier, raw_attrs, env)

View Source
Link to this macro

import_directives(type_module_ast, opts \\ [])

View Source (macro)

Import directives from another module

To selectively import directives you can use the :only and :except opts.

placement

Placement

Top level in module.

examples

Examples

import_directives MyApp.Schema.Directives

import_directives MyApp.Schema.Directives.{DirectivesA, DirectivesB}

import_directives MyApp.Schema.Directives, only: [:foo]

import_directives MyApp.Schema.Directives, except: [:bar]
Link to this macro

import_fields(source_criteria, opts \\ [])

View Source (macro)

Import fields from another object

example

Example

object :news_queries do
  field :all_links, list_of(:link)
  field :main_story, :link
end

object :admin_queries do
  field :users, list_of(:user)
  field :pending_posts, list_of(:post)
end

query do
  import_fields :news_queries
  import_fields :admin_queries
end

Import fields can also be used on objects created inside other modules that you have used import_types on.

defmodule MyApp.Schema.NewsTypes do
  use Absinthe.Schema.Notation

  object :news_queries do
    field :all_links, list_of(:link)
    field :main_story, :link
  end
end
defmodule MyApp.Schema.Schema do
  use Absinthe.Schema

  import_types MyApp.Schema.NewsTypes

  query do
    import_fields :news_queries
    # ...
  end
end
Link to this macro

import_sdl(opts)

View Source (macro)
@spec import_sdl([import_sdl_option(), ...]) :: Macro.t()

Import types defined using the Schema Definition Language (SDL).

To add resolvers and middleware to the schema, use the callbacks defined in Absinthe.Schema, like Absinthe.Schema.hydrate/2.

placement

Placement

Top level in module.

examples

Examples

Directly embedded SDL:

import_sdl """
type Query {
  posts: [Post]
}

type Post {
  title: String!
  body: String!
}
"""

Loaded from a file location (supporting recompilation on change):

import_sdl path: "/path/to/sdl.graphql"

TODO: Example for dynamic loading during init

Link to this macro

import_sdl(sdl, opts \\ [])

View Source (macro)
@spec import_sdl(String.t() | Macro.t(), [import_sdl_option()]) :: Macro.t()
Link to this macro

import_type_extensions(type_module_ast, opts \\ [])

View Source (macro)

Import type_extensions from another module

To selectively import type_extensions you can use the :only and :except opts.

placement

Placement

Top level in module.

examples

Examples

import_type_extensions MyApp.Schema.TypeExtensions

import_type_extensions MyApp.Schema.TypeExtensions.{TypeExtensionsA, TypeExtensionsB}

import_type_extensions MyApp.Schema.TypeExtensions, only: [:foo]

import_type_extensions MyApp.Schema.TypeExtensions, except: [:bar]
Link to this macro

import_types(type_module_ast, opts \\ [])

View Source (macro)

Import types from another module

Very frequently your schema module will simply have the query and mutation blocks, and you'll want to break out your other types into other modules. This macro imports those types for use the current module.

To selectively import types you can use the :only and :except opts.

placement

Placement

Top level in module.

examples

Examples

import_types MyApp.Schema.Types

import_types MyApp.Schema.Types.{TypesA, TypesB}

import_types MyApp.Schema.Types, only: [:foo]

import_types MyApp.Schema.Types, except: [:bar]
Link to this macro

input_object(identifier, attrs \\ [], list)

View Source (macro)

Defines an input object

See Absinthe.Type.InputObject

placement

Placement

Top level in module or in an extend block.

examples

Examples

input_object :contact_input do
  field :email, non_null(:string)
end
Link to this macro

interface(identifier)

View Source (macro)

Declare an implemented interface for an object.

Adds an Absinthe.Type.Interface to your schema.

See also interfaces/1, which can be used for multiple interfaces, and interface/3, used to define interfaces themselves.

placement

Placement

Allowed under: interface object

examples

Examples

object :car do
  interface :vehicle
  # ...
end
Link to this macro

interface(identifier, attrs \\ [], list)

View Source (macro)

Define an interface type.

Adds an Absinthe.Type.Interface to your schema.

Also see interface/1 and interfaces/1, which declare that an object implements one or more interfaces.

placement

Placement

Top level in module or in an extend block.

examples

Examples

interface :vehicle do
  field :wheel_count, :integer
end

object :rally_car do
  field :wheel_count, :integer
  interface :vehicle
end
Link to this macro

interfaces(ifaces)

View Source (macro)

Declare implemented interfaces for an object.

See also interface/1, which can be used for one interface, and interface/3, used to define interfaces themselves.

placement

Placement

Allowed under: interface object

examples

Examples

object :car do
  interfaces [:vehicle, :branded]
  # ...
end
Link to this macro

is_type_of(func_ast)

View Source (macro)

placement

Placement

Allowed under: object

Link to this function

lift_functions(schema, origin)

View Source
Link to this function

lift_functions(node, acc, origin)

View Source

Marks a type reference as a list of the given type

See field/3 for examples

Link to this macro

meta(keyword_list)

View Source (macro)

Defines list of metadata's key/value pair for a custom type.

This is generally used to facilitate libraries that want to augment Absinthe functionality

examples

Examples

object :user do
  meta cache: true, ttl: 22_000
end

object :user, meta: [cache: true, ttl: 22_000] do
  # ...
end

The meta can be accessed via the Absinthe.Type.meta/2 function.

user_type = Absinthe.Schema.lookup_type(MyApp.Schema, :user)

Absinthe.Type.meta(user_type, :cache)
#=> true

Absinthe.Type.meta(user_type)
#=> [cache: true, ttl: 22_000]

placement

Placement

Allowed under: directive enum extend field input_object interface object scalar union

Link to this macro

meta(key, value)

View Source (macro)

Defines a metadata key/value pair for a custom type.

For more info see meta/1

examples

Examples

meta :cache, false

placement

Placement

Allowed under: directive enum extend field input_object interface object scalar union

Link to this macro

middleware(new_middleware, opts \\ [])

View Source (macro)
Link to this macro

non_null(type)

View Source (macro)

Marks a type reference as non null

See field/3 for examples

Link to this macro

object(identifier, attrs \\ [], block)

View Source (macro)

Define an object type.

Adds an Absinthe.Type.Object to your schema.

placement

Placement

Top level in module or in an extend block.

examples

Examples

Basic definition:

object :car do
  # ...
end

Providing a custom name:

object :car, name: "CarType" do
  # ...
end

Declare a directive as operating an a AST node type

See directive/2

placement

Placement

Allowed under: directive

Link to this macro

parse(func_ast)

View Source (macro)

Defines a parse function for a scalar type

The specified parse function is used on incoming data to transform it into an elixir datastructure.

It should return {:ok, value} or :error

placement

Placement

Allowed under: scalar

Link to this function

put_reference(attrs, env)

View Source
Link to this function

record!(env, type, identifier, attrs, block)

View Source
Link to this function

record_applied_directive!(env, name, attrs)

View Source
Link to this function

record_config!(env, fun_ast)

View Source
Link to this function

record_extend!(caller, attrs, type_block, extend_block)

View Source
Link to this function

record_middleware!(env, new_middleware, opts)

View Source
Link to this function

record_schema!(env, block)

View Source
Link to this function

record_trigger!(env, mutations, attrs)

View Source
Link to this macro

repeatable(bool)

View Source (macro)

Set whether the directive can be applied multiple times an entity.

If omitted, defaults to false

placement

Placement

Allowed under: directive

Link to this macro

resolve(func_ast)

View Source (macro)

Defines a resolve function for a field

Specify a 2 or 3 arity function to call when resolving a field.

You can either hard code a particular anonymous function, or have a function call that returns a 2 or 3 arity anonymous function. See examples for more information.

Note that when using a hard coded anonymous function, the function will not capture local variables.

3-arity-functions

3 Arity Functions

The first argument to the function is the parent entity.

{
  user(id: 1) {
    name
  }
}

A resolution function on the name field would have the result of the user(id: 1) field as its first argument. Top level fields have the root_value as their first argument. Unless otherwise specified, this defaults to an empty map.

The second argument to the resolution function is the field arguments. The final argument is an Absinthe.Resolution struct, which includes information like the context and other execution data.

2-arity-function

2 Arity Function

Exactly the same as the 3 arity version, but without the first argument (the parent entity)

placement

Placement

Allowed under: field

examples

Examples

query do
  field :person, :person do
    arg :id, non_null(:id)
    resolve &Person.resolve/2
  end
end
query do
  field :person, :person do
    arg :id, non_null(:id)
    resolve fn %{id: id}, _ ->
      {:ok, Person.find(id)}
    end
  end
end
query do
  field :person, :person do
    arg :id, non_null(:id)
    resolve lookup(:person)
  end
end

def lookup(:person) do
  fn %{id: id}, _ ->
    {:ok, Person.find(id)}
  end
end
Link to this macro

resolve_type(func_ast)

View Source (macro)

Define a type resolver for a union or interface.

See also:

placement

Placement

Allowed under: interface union

examples

Examples

interface :entity do
  # ...
  resolve_type fn
    %{employee_count: _},  _ ->
      :business
    %{age: _}, _ ->
      :person
  end
end
Link to this macro

scalar(identifier, attrs)

View Source (macro)

Defines a scalar type

See scalar/3

Link to this macro

scalar(identifier, attrs, list)

View Source (macro)

Define a scalar type

A scalar type requires parse/1 and serialize/1 functions.

placement

Placement

Top level in module or in an extend block.

examples

Examples

scalar :isoz_datetime, description: "UTC only ISO8601 date time" do
  parse &Timex.parse(&1, "{ISO:Extended:Z}")
  serialize &Timex.format!(&1, "{ISO:Extended:Z}")
end

Declare a schema

Optional declaration of the schema. Useful if you want to add directives to your schema declaration

placement

Placement

Top level in module or in an extend block.

examples

Examples

schema do
  directive :feature
  field :query, :query
  # ...
end
Link to this macro

serialize(func_ast)

View Source (macro)

Defines a serialization function for a scalar type

The specified serialize function is used on outgoing data. It should simply return the desired external representation.

placement

Placement

Allowed under: scalar

Link to this macro

trigger(mutations, attrs)

View Source (macro)

Sets triggers for a subscription, and configures which topics to publish to when that subscription is triggered.

A trigger is the name of a mutation. When that mutation runs, data is pushed to the clients who are subscribed to the subscription.

A subscription can have many triggers, and a trigger can push to many topics.

placement

Placement

Allowed under: field

example

Example

mutation do
  field :gps_event, :gps_event
  field :user_checkin, :user
end

subscription do
  field :location_update, :user do
    arg :user_id, non_null(:id)

    config fn args, _ ->
      {:ok, topic: args.user_id}
    end

    trigger :gps_event, topic: fn gps_event ->
      gps_event.user_id
    end

    # Trigger on a list of mutations
    trigger [:user_checkin], topic: fn user ->
      # Returning a list of topics triggers the subscription for each of the topics in the list.
      [user.id, user.friend.id]
    end
  end
end

Trigger functions are only called once per event, so database calls within them do not present a significant burden.

See the Absinthe.Schema.subscription/2 macro docs for additional details

Defines the types possible under a union type

See union/3

placement

Placement

Allowed under: union

Link to this macro

union(identifier, attrs \\ [], list)

View Source (macro)

Defines a union type

See Absinthe.Type.Union

placement

Placement

Top level in module or in an extend block.

examples

Examples

union :search_result do
  description "A search result"

  types [:person, :business]
  resolve_type fn
    %Person{}, _ -> :person
    %Business{}, _ -> :business
  end
end
Link to this macro

value(identifier, raw_attrs \\ [])

View Source (macro)

Defines a value possible under an enum type

See enum/3

placement

Placement

Allowed under: enum

Link to this macro

values(values)

View Source (macro)