Current section
Files
Jump to
Current section
Files
lib/graphql_query/schema.ex
defmodule GraphqlQuery.Schema do
@moduledoc """
Behaviour and utilities for GraphQL schema management.
Defines the contract for modules that provide GraphQL schemas and includes
a `__using__` macro for easy schema module setup with automatic file loading
and validation.
Options for `use GraphqlQuery.Schema`:
* `:schema_path` - Path to a `.graphql` or `.gql` schema file to load.
* `:absinthe_schema` - An Absinthe schema module to extract the schema from.
## Example
defmodule MyApp.Schema do
use GraphqlQuery.Schema, schema_path: "priv/schema.graphql"
end
defmodule MyApp.AbsintheSchema do
use GraphqlQuery.Schema, absinthe_schema: MyAppWeb.Graphql.Schema
end
# The schema will be automatically loaded from the file
MyApp.Schema.schema()
#=> %GraphqlQuery.Document{type: :schema, query: "type Query { user(id: ID!): User } ..."
# For Absinthe, the schema is extracted at compile time
MyApp.AbsintheSchema.schema()
#=> %GraphqlQuery.Document{type: :schema, query: "type Query { user(id: ID!): User } ..."
# Get the file path
MyApp.Schema.schema_path()
#=> "priv/schema.graphql"
"""
@callback schema() :: GraphqlQuery.Document.t()
@callback schema_path() :: String.t() | nil
defstruct [:schema, :schema_path]
defmacro __using__(opts) do
file_path = Keyword.get(opts, :schema_path)
absinthe = Keyword.get(opts, :absinthe_schema)
quote do
@behaviour GraphqlQuery.Schema
use GraphqlQuery
cond do
unquote(file_path) ->
unquote(file_path_ast(file_path))
unquote(absinthe) ->
unquote(absinthe_ast(absinthe, __CALLER__.file))
true ->
@impl GraphqlQuery.Schema
def schema_path, do: unquote(__CALLER__.file)
defoverridable schema_path: 0
end
end
end
defp file_path_ast(file_path) do
quote do
@impl GraphqlQuery.Schema
def schema do
gql_from_file(unquote(file_path), type: :schema)
end
@impl GraphqlQuery.Schema
def schema_path, do: unquote(file_path)
end
end
defp absinthe_ast(absinthe, file_path) do
quote do
@content GraphqlQuery.Schema.Absinthe.schema_from_absinthe!(unquote(absinthe))
@impl GraphqlQuery.Schema
def schema do
gql [type: :schema, evaluate: true], @content
end
@impl GraphqlQuery.Schema
def schema_path, do: unquote(file_path)
end
end
end