2020-05-02 10:35:12 +12:00
|
|
|
defmodule AshGraphql.Api do
|
2020-08-14 09:39:59 +12:00
|
|
|
@moduledoc "The entrypoint for adding graphql behavior to an Ash API"
|
|
|
|
|
|
|
|
@graphql %Ash.Dsl.Section{
|
|
|
|
name: :graphql,
|
|
|
|
describe: """
|
|
|
|
Global configuration for graphql
|
|
|
|
""",
|
|
|
|
schema: [
|
|
|
|
authorize?: [
|
|
|
|
type: :boolean,
|
|
|
|
doc: "Whether or not to perform authorization for this API",
|
|
|
|
default: true
|
|
|
|
]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
use Ash.Dsl.Extension, sections: [@graphql]
|
|
|
|
|
|
|
|
def authorize?(api) do
|
2020-09-24 12:54:57 +12:00
|
|
|
Extension.get_opt(api, [:graphql], :authorize?, true)
|
2020-08-14 09:39:59 +12:00
|
|
|
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.extensions(resource)
|
|
|
|
end)
|
|
|
|
|> Enum.flat_map(&AshGraphql.Resource.mutations(api, &1, schema))
|
|
|
|
end
|
|
|
|
|
|
|
|
@doc false
|
2020-12-01 13:04:59 +13:00
|
|
|
def type_definitions(api, schema) do
|
2020-08-14 09:39:59 +12:00
|
|
|
resource_types =
|
|
|
|
api
|
|
|
|
|> Ash.Api.resources()
|
|
|
|
|> Enum.filter(fn resource ->
|
|
|
|
AshGraphql.Resource in Ash.Resource.extensions(resource)
|
|
|
|
end)
|
|
|
|
|> Enum.flat_map(fn resource ->
|
2020-09-24 12:54:57 +12:00
|
|
|
AshGraphql.Resource.type_definitions(resource, api, schema) ++
|
2020-08-14 09:39:59 +12:00
|
|
|
AshGraphql.Resource.mutation_types(resource, schema)
|
|
|
|
end)
|
|
|
|
|
2020-12-01 13:04:59 +13:00
|
|
|
resource_types
|
|
|
|
end
|
|
|
|
|
|
|
|
def global_type_definitions(schema) do
|
|
|
|
[mutation_error(schema), relationship_change(schema), sort_order(schema)]
|
2020-08-14 09:39:59 +12:00
|
|
|
end
|
|
|
|
|
2020-11-06 14:59:06 +13:00
|
|
|
defp sort_order(schema) do
|
|
|
|
%Absinthe.Blueprint.Schema.EnumTypeDefinition{
|
|
|
|
module: schema,
|
|
|
|
name: "SortOrder",
|
|
|
|
values: [
|
|
|
|
%Absinthe.Blueprint.Schema.EnumValueDefinition{
|
|
|
|
module: schema,
|
|
|
|
identifier: :desc,
|
|
|
|
name: "DESC",
|
|
|
|
value: :desc
|
|
|
|
},
|
|
|
|
%Absinthe.Blueprint.Schema.EnumValueDefinition{
|
|
|
|
module: schema,
|
|
|
|
identifier: :asc,
|
|
|
|
name: "ASC",
|
|
|
|
value: :asc
|
|
|
|
}
|
|
|
|
],
|
|
|
|
identifier: :sort_order
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2020-08-14 09:39:59 +12:00
|
|
|
defp relationship_change(schema) do
|
2020-08-27 05:56:08 +12:00
|
|
|
%Absinthe.Blueprint.Schema.InputObjectTypeDefinition{
|
2020-08-14 09:39:59 +12:00
|
|
|
description: "A set of changes to apply to a relationship",
|
|
|
|
fields: relationship_change_fields(schema),
|
|
|
|
identifier: :relationship_change,
|
|
|
|
module: schema,
|
|
|
|
name: "RelationshipChange"
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
defp relationship_change_fields(schema) do
|
|
|
|
[
|
|
|
|
%Absinthe.Blueprint.Schema.FieldDefinition{
|
|
|
|
description: "Ids to add to the relationship",
|
|
|
|
identifier: :add,
|
|
|
|
module: schema,
|
|
|
|
name: "add",
|
|
|
|
type: %Absinthe.Blueprint.TypeReference.List{
|
|
|
|
of_type: :id
|
|
|
|
}
|
|
|
|
},
|
|
|
|
%Absinthe.Blueprint.Schema.FieldDefinition{
|
|
|
|
description: "Ids to remove from the relationship",
|
|
|
|
identifier: :remove,
|
|
|
|
module: schema,
|
|
|
|
name: "remove",
|
|
|
|
type: %Absinthe.Blueprint.TypeReference.List{
|
|
|
|
of_type: :id
|
|
|
|
}
|
|
|
|
},
|
|
|
|
%Absinthe.Blueprint.Schema.FieldDefinition{
|
|
|
|
description:
|
|
|
|
"Ids to replace the relationship with. Takes precendence over removal and addition",
|
|
|
|
identifier: :replace,
|
|
|
|
module: schema,
|
|
|
|
name: "replace",
|
|
|
|
type: %Absinthe.Blueprint.TypeReference.List{
|
|
|
|
of_type: :id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
|
|
|
defp mutation_error(schema) do
|
|
|
|
%Absinthe.Blueprint.Schema.ObjectTypeDefinition{
|
|
|
|
description: "An error generated by a failed mutation",
|
|
|
|
fields: error_fields(schema),
|
|
|
|
identifier: :mutation_error,
|
|
|
|
module: schema,
|
|
|
|
name: "MutationError"
|
|
|
|
}
|
|
|
|
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: "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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
2020-05-02 10:35:12 +12:00
|
|
|
end
|
|
|
|
end
|