Packages
ash_graphql
0.17.4
1.9.4
1.9.3
1.9.2
1.9.1
1.9.0
1.8.5
1.8.4
1.8.3
1.8.2
1.8.1
1.8.0
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.0
1.5.1
1.5.0
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.5
1.0.0-rc.4
retired
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.28.1
0.28.0
0.27.1
0.27.0
0.26.9
0.26.8
0.26.7
0.26.6
0.26.5
0.26.4
0.26.3
0.26.2
0.26.0
0.25.13
0.25.12
0.25.10
0.25.9
0.25.8
0.25.7
0.25.6
0.25.5
0.25.4
0.25.3
0.25.2
0.25.1
0.25.0
0.24.1
0.24.0
0.23.3
0.23.2
0.23.1
0.23.0
0.22.13
0.22.12
0.22.11
0.22.10
0.22.9
0.22.8
0.22.7
0.22.6
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.0
retired
0.20.5
0.20.4
0.20.3
0.20.2
0.20.1
0.20.0-rc.3
0.20.0-rc.2
0.20.0-rc.1
0.20.0-rc.0
0.19.0
0.18.0-rc0
0.17.5
0.17.5-rc0
0.17.4
0.17.2
0.17.1
0.17.0
0.16.28
0.16.27
0.16.26
0.16.25
0.16.24
0.16.23
0.16.22
0.16.21
0.16.20
0.16.18-rc5
0.16.18-rc4
0.16.18-rc3
0.16.18-rc2
0.16.18-rc1
0.16.18-rc0
0.16.17
0.16.16
0.16.15
0.16.14
0.16.13
0.16.12
0.16.11
0.16.10
0.16.9
0.16.8
0.16.7
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.1
0.14.0
0.13.1
0.13.0
0.12.5
0.12.4
0.12.3
0.12.1
0.12.0
0.10.0
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.3
0.1.2
The extension for building GraphQL APIs with Ash
Current section
Files
Jump to
Current section
Files
lib/api/api.ex
defmodule AshGraphql.Api do
@graphql %Ash.Dsl.Section{
name: :graphql,
describe: """
Global configuration for graphql
""",
examples: [
"""
graphql do
authorize? false # To skip authorization for this API
end
"""
],
schema: [
authorize?: [
type: :boolean,
doc: "Whether or not to perform authorization for this API",
default: true
],
root_level_errors?: [
type: :boolean,
default: false,
doc:
"By default, mutation errors are shown in their result object's errors key, but this setting places those errors in the top level errors list"
],
show_raised_errors?: [
type: :boolean,
default: false,
doc:
"For security purposes, if an error is *raised* then Ash simply shows a generic error. If you want to show those errors, set this to true."
],
stacktraces?: [
type: :boolean,
doc: "Whether or not to include stacktraces in generated errors",
default: true
],
debug?: [
type: :boolean,
doc: "Whether or not to log (extremely verbose) debug information",
default: false
]
]
}
@sections [@graphql]
@moduledoc """
The entrypoint for adding graphql behavior to an Ash API
# Table of Contents
#{Ash.Dsl.Extension.doc_index(@sections)}
#{Ash.Dsl.Extension.doc(@sections)}
"""
use Ash.Dsl.Extension, sections: @sections
def authorize?(api) do
Extension.get_opt(api, [:graphql], :authorize?, true)
end
def root_level_errors?(api) do
Extension.get_opt(api, [:graphql], :root_level_errors?, false, true)
end
def show_raised_errors?(api) do
Extension.get_opt(api, [:graphql], :show_raised_errors?, false, true)
end
def debug?(api) do
Extension.get_opt(api, [:graphql], :debug?, false)
end
def stacktraces?(api) do
Extension.get_opt(api, [:graphql], :stacktraces?, false)
end
@doc false
def queries(api, schema) do
api
|> Ash.Api.resources()
|> Enum.flat_map(&AshGraphql.Resource.queries(api, &1, schema))
end
@doc false
def mutations(api, schema) do
api
|> Ash.Api.resources()
|> Enum.filter(fn resource ->
AshGraphql.Resource in Ash.Resource.Info.extensions(resource)
end)
|> Enum.flat_map(&AshGraphql.Resource.mutations(api, &1, schema))
end
@doc false
def type_definitions(api, schema, first?) do
resource_types =
api
|> Ash.Api.resources()
|> Enum.reject(&Ash.Resource.Info.embedded?/1)
|> Enum.flat_map(fn resource ->
if AshGraphql.Resource in Ash.Resource.Info.extensions(resource) do
AshGraphql.Resource.type_definitions(resource, api, schema) ++
AshGraphql.Resource.mutation_types(resource, schema)
else
AshGraphql.Resource.no_graphql_types(resource, schema)
end
end)
if Enum.any?(Ash.Api.resources(api), &AshGraphql.Resource.relay?/1) && first? do
[
%Absinthe.Blueprint.Schema.InterfaceTypeDefinition{
description: "A relay node",
name: "Node",
fields: [
%Absinthe.Blueprint.Schema.FieldDefinition{
description: "A unique identifier",
identifier: :id,
module: schema,
name: "id",
type: %Absinthe.Blueprint.TypeReference.NonNull{of_type: :id}
}
],
identifier: :node,
module: schema
}
| resource_types
]
else
resource_types
end
end
def global_type_definitions(schema, env) do
[mutation_error(schema, env), sort_order(schema, env)]
end
defp sort_order(schema, env) do
%Absinthe.Blueprint.Schema.EnumTypeDefinition{
module: schema,
name: "SortOrder",
values: [
%Absinthe.Blueprint.Schema.EnumValueDefinition{
module: schema,
identifier: :desc,
__reference__: AshGraphql.Resource.ref(env),
name: "DESC",
value: :desc
},
%Absinthe.Blueprint.Schema.EnumValueDefinition{
module: schema,
identifier: :asc,
__reference__: AshGraphql.Resource.ref(env),
name: "ASC",
value: :asc
}
],
identifier: :sort_order,
__reference__: AshGraphql.Resource.ref(env)
}
end
defp mutation_error(schema, env) do
%Absinthe.Blueprint.Schema.ObjectTypeDefinition{
description: "An error generated by a failed mutation",
fields: error_fields(schema),
identifier: :mutation_error,
module: schema,
name: "MutationError",
__reference__: AshGraphql.Resource.ref(env)
}
end
defp error_fields(schema) do
[
%Absinthe.Blueprint.Schema.FieldDefinition{
description: "The human readable error message",
identifier: :message,
module: schema,
name: "message",
type: :string
},
%Absinthe.Blueprint.Schema.FieldDefinition{
description: "A shorter error message, with vars not replaced",
identifier: :short_message,
module: schema,
name: "short_message",
type: :string
},
%Absinthe.Blueprint.Schema.FieldDefinition{
description: "Replacements for the short message",
identifier: :vars,
module: schema,
name: "vars",
type: :json
},
%Absinthe.Blueprint.Schema.FieldDefinition{
description: "An error code for the given error",
identifier: :code,
module: schema,
name: "code",
type: :string
},
%Absinthe.Blueprint.Schema.FieldDefinition{
description: "The field or fields that produced the error",
identifier: :fields,
module: schema,
name: "fields",
type: %Absinthe.Blueprint.TypeReference.List{
of_type: :string
}
}
]
end
end