Current section

Files

Jump to
absinthe_relay lib absinthe relay mutation.ex
Raw

lib/absinthe/relay/mutation.ex

defmodule Absinthe.Relay.Mutation do
@moduledoc """
Support for building mutations with single inputs and client mutation IDs.
The `payload` macro can be used by schema designers to support mutation
fields that receive a single input object argument with a client mutation ID
and return that ID as part of the response payload.
More information can be found at:
- https://facebook.github.io/relay/docs/graphql-mutations.html
- https://facebook.github.io/relay/graphql/mutations.htm
## Example
In this example we add a mutation field `:simple_mutation` that
accepts an `input` argument (which is defined for us automatically)
which contains an `:input_data` field.
We also declare the output will contain a field, `:result`.
Notice the `resolve` function doesn't need to know anything about the
wrapping `input` argument -- it only concerns itself with the contents
-- and the client mutation ID doesn't need to be dealt with, either. It
will be returned as part of the response payload automatically.
```
mutation do
payload field :simple_mutation do
input do
field :input_data, non_null(:integer)
end
output do
field :result, :integer
end
resolve fn
%{input_data: input_data}, _ ->
# Some mutation side-effect here
{:ok, %{result: input_data * 2}}
end
end
end
```
Here's a query document that would hit this field:
```graphql
mutation DoSomethingSimple {
simpleMutation(input: {inputData: 2, clientMutationId: "abc"}) {
result
clientMutationId
}
}
```
And here's the response:
```json
{
"data": {
"simpleMutation": {
"result": 4,
"clientMutationId": "abc"
}
}
}
```
Note the above code would create the following types in our schema, ad hoc:
- `SimpleMutationInput`
- `SimpleMutationPayload`
For this reason, the identifier passed to `payload field` must be unique
across your schema.
## Macros
For more details on `payload` and other mutation-related macros, see
`Absinthe.Relay.Mutation.Notation`.
"""
@doc false
# System resolver to extract values from the input and return the
# client mutation ID as part of the response.
def resolve_with_input(%{input: %{client_mutation_id: mut_id} = input}, info, designer_resolver) do
case designer_resolver.(input, info) do
{flag, value} when is_map(value) ->
{flag, Map.put(value, :client_mutation_id, mut_id)}
other ->
# On your own!
other
end
end
def resolve_with_input(_, info, designer_resolver) do
designer_resolver.(%{}, info)
end
end