Skip to content

Commit

Permalink
improvement: make mutation arguments non-null
Browse files Browse the repository at this point in the history
As discussed in #105 and #110, put this behind an opt-in configuration to avoid
breaking existing code.
The ID in update mutations is always non-null if non-null mutation arguments are
allowed, while input is non-null if it's allowed _and_ there is at least a
non-null field in the input.

Document the newly added config variable in the getting started guide.
  • Loading branch information
rbino committed Jan 31, 2024
1 parent af4193f commit 1236da9
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
1 change: 1 addition & 0 deletions documentation/tutorials/getting-started-with-graphql.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ in `config/config.exs`

```elixir
config :ash_graphql, :default_managed_relationship_type_name_template, :action_name
config :ash_graphql, :allow_non_null_mutation_arguments?, true
```

This won't be necessary after the next major release, where this new configuration will be the default.
Expand Down
38 changes: 31 additions & 7 deletions lib/resource/resource.ex
Original file line number Diff line number Diff line change
Expand Up @@ -552,14 +552,14 @@ defmodule AshGraphql.Resource do
[] ->
[]

_ ->
fields ->
[
%Absinthe.Blueprint.Schema.InputValueDefinition{
identifier: :input,
module: schema,
name: "input",
placement: :argument_definition,
type: String.to_atom("#{name}_input")
type: mutation_input_type(name, fields)
}
]
end
Expand Down Expand Up @@ -621,14 +621,14 @@ defmodule AshGraphql.Resource do
[] ->
[]

_ ->
fields ->
[
%Absinthe.Blueprint.Schema.InputValueDefinition{
identifier: :input,
module: schema,
name: "input",
placement: :argument_definition,
type: String.to_atom("#{mutation.name}_input")
type: mutation_input_type(mutation.name, fields)
}
]
end
Expand Down Expand Up @@ -672,15 +672,15 @@ defmodule AshGraphql.Resource do
[] ->
mutation_args(mutation, resource, schema)

_ ->
fields ->
mutation_args(mutation, resource, schema) ++
[
%Absinthe.Blueprint.Schema.InputValueDefinition{
identifier: :input,
module: schema,
name: "input",
placement: :argument_definition,
type: String.to_atom("#{mutation.name}_input"),
type: mutation_input_type(mutation.name, fields),
__reference__: ref(__ENV__)
}
]
Expand Down Expand Up @@ -730,20 +730,44 @@ defmodule AshGraphql.Resource do
|> Enum.concat(mutation_read_args(mutation, resource, schema))
end

@allow_non_null_mutation_arguments? Application.compile_env(
:ash_graphql,
:allow_non_null_mutation_arguments?,
false
)

defp mutation_args(mutation, resource, schema) do
[
%Absinthe.Blueprint.Schema.InputValueDefinition{
identifier: :id,
module: schema,
name: "id",
placement: :argument_definition,
type: :id,
type: maybe_wrap_non_null(:id, @allow_non_null_mutation_arguments?),
__reference__: ref(__ENV__)
}
| mutation_read_args(mutation, resource, schema)
]
end

# sobelow_skip ["DOS.StringToAtom"]
defp mutation_input_type(mutation_name, mutation_fields) do
any_non_null_field? =
mutation_fields
|> Enum.any?(fn
%Absinthe.Blueprint.Schema.FieldDefinition{
type: %Absinthe.Blueprint.TypeReference.NonNull{}
} ->
true

_ ->
false
end)

String.to_atom("#{mutation_name}_input")
|> maybe_wrap_non_null(any_non_null_field? and @allow_non_null_mutation_arguments?)
end

defp mutation_read_args(%{read_action: read_action}, resource, schema) do
read_action =
cond do
Expand Down

0 comments on commit 1236da9

Please sign in to comment.