GreenFairy.Schema (GreenFairy v0.3.0)

View Source

Schema assembly with graph-based type discovery.

Automatically discovers types by walking the type graph from your root query/mutation/subscription modules.

Basic Usage

defmodule MyApp.GraphQL.Schema do
  use GreenFairy.Schema,
    query: MyApp.GraphQL.RootQuery,
    mutation: MyApp.GraphQL.RootMutation,
    subscription: MyApp.GraphQL.RootSubscription
end

The schema will automatically discover all types reachable from your roots.

Inline Root Definitions

Or define roots inline:

defmodule MyApp.GraphQL.Schema do
  use GreenFairy.Schema

  root_query do
    field :health, :string do
      resolve fn _, _, _ -> {:ok, "ok"} end
    end
  end

  root_mutation do
    field :noop, :boolean do
      resolve fn _, _, _ -> {:ok, true} end
    end
  end
end

Options

  • :query - Module to use as root query (or use root_query macro)
  • :mutation - Module to use as root mutation (or use root_mutation macro)
  • :subscription - Module to use as root subscription (or use root_subscription macro)
  • :repo - Ecto repo module for database operations and Node resolution
  • :global_id - Custom GlobalId implementation (defaults to GreenFairy.GlobalId.Base64)
  • :dataloader - DataLoader configuration
    • :sources - List of {source_name, repo_or_source} tuples

Custom Global IDs

You can implement custom global ID encoding/decoding:

defmodule MyApp.CustomGlobalId do
  @behaviour GreenFairy.GlobalId

  @impl true
  def encode(type_name, id), do: # your encoding

  @impl true
  def decode(global_id), do: # your decoding
end

use GreenFairy.Schema,
  query: MyApp.RootQuery,
  repo: MyApp.Repo,
  global_id: MyApp.CustomGlobalId

Type Discovery

Types are discovered by walking the graph from your root modules:

  1. Start at Query/Mutation/Subscription modules
  2. Extract type references from field definitions
  3. Recursively follow references to discover all reachable types
  4. Only import types actually used in your schema

This means:

  • Types can live anywhere in your codebase
  • Unused types are not imported
  • Clear dependency graph
  • Supports circular references

Summary

Functions

Generates resolve_type function for an interface based on discovered implementors.

Define inline mutation fields for this schema.

Define inline query fields for this schema.

Define inline subscription fields for this schema.

Functions

resolve_type_for(value, struct_mapping)

Generates resolve_type function for an interface based on discovered implementors.

This can be called manually or used by the schema to auto-generate resolve_type functions for interfaces.

Example

def resolve_type(value, _) do
  GreenFairy.Schema.resolve_type_for(value, %{
    MyApp.User => :user,
    MyApp.Post => :post
  })
end

root_mutation(list)

(macro)

Define inline mutation fields for this schema.

root_mutation do
  field :noop, :boolean do
    resolve fn _, _, _ -> {:ok, true} end
  end
end

root_query(list)

(macro)

Define inline query fields for this schema.

root_query do
  field :health, :string do
    resolve fn _, _, _ -> {:ok, "ok"} end
  end
end

root_subscription(list)

(macro)

Define inline subscription fields for this schema.

root_subscription do
  field :events, :event do
    config fn _, _ -> {:ok, topic: "*"} end
  end
end