graphene/docs/types/mutations.rst

184 lines
4.2 KiB
ReStructuredText
Raw Permalink Normal View History

Mutations
=========
A Mutation is a special ObjectType that also defines an Input.
Quick example
-------------
This example defines a Mutation:
.. code:: python
2017-03-01 14:54:06 +03:00
import graphene
2017-03-01 14:54:06 +03:00
class CreatePerson(graphene.Mutation):
2017-07-27 08:33:59 +03:00
class Arguments:
2017-03-01 14:54:06 +03:00
name = graphene.String()
2017-03-01 14:54:06 +03:00
ok = graphene.Boolean()
person = graphene.Field(lambda: Person)
def mutate(root, info, name):
2017-07-24 09:16:51 +03:00
person = Person(name=name)
2017-03-01 14:54:06 +03:00
ok = True
return CreatePerson(person=person, ok=ok)
**person** and **ok** are the output fields of the Mutation when it is
resolved.
2018-10-20 12:16:29 +03:00
**Arguments** attributes are the arguments that the Mutation
``CreatePerson`` needs for resolving, in this case **name** will be the
only argument for the mutation.
**mutate** is the function that will be applied once the mutation is
called. This method is just a special resolver that we can change
data within. It takes the same arguments as the standard query :ref:`ResolverArguments`.
So, we can finish our schema like this:
.. code:: python
# ... the Mutation Class
class Person(graphene.ObjectType):
name = graphene.String()
2017-02-21 09:12:55 +03:00
age = graphene.Int()
class MyMutations(graphene.ObjectType):
create_person = CreatePerson.Field()
# We must define a query for our schema
class Query(graphene.ObjectType):
person = graphene.Field(Person)
schema = graphene.Schema(query=Query, mutation=MyMutations)
Executing the Mutation
----------------------
Then, if we query (``schema.execute(query_str)``) the following:
2016-09-25 15:01:12 +03:00
.. code::
mutation myFirstMutation {
createPerson(name:"Peter") {
person {
name
}
ok
}
}
We should receive:
.. code:: json
{
"createPerson": {
"person" : {
"name": "Peter"
},
"ok": true
}
}
InputFields and InputObjectTypes
----------------------------------
InputFields are used in mutations to allow nested input data for mutations
To use an InputField you define an InputObjectType that specifies the structure of your input data
.. code:: python
import graphene
class PersonInput(graphene.InputObjectType):
2017-07-24 09:16:51 +03:00
name = graphene.String(required=True)
age = graphene.Int(required=True)
class CreatePerson(graphene.Mutation):
2017-07-27 08:33:59 +03:00
class Arguments:
2017-07-24 09:16:51 +03:00
person_data = PersonInput(required=True)
2017-07-24 09:16:51 +03:00
person = graphene.Field(Person)
def mutate(root, info, person_data=None):
2017-07-24 09:16:51 +03:00
person = Person(
name=person_data.name,
age=person_data.age
)
return CreatePerson(person=person)
Note that **name** and **age** are part of **person_data** now
Using the above mutation your new query would look like this:
.. code::
mutation myFirstMutation {
createPerson(personData: {name:"Peter", age: 24}) {
person {
2016-11-15 04:50:41 +03:00
name,
age
}
}
}
InputObjectTypes can also be fields of InputObjectTypes allowing you to have
as complex of input data as you need
.. code:: python
import graphene
class LatLngInput(graphene.InputObjectType):
lat = graphene.Float()
lng = graphene.Float()
#A location has a latlng associated to it
class LocationInput(graphene.InputObjectType):
name = graphene.String()
2017-01-10 17:45:32 +03:00
latlng = graphene.InputField(LatLngInput)
Output type example
-------------------
To return an existing ObjectType instead of a mutation-specific type, set the **Output** attribute to the desired ObjectType:
.. code:: python
import graphene
class CreatePerson(graphene.Mutation):
class Arguments:
name = graphene.String()
Output = Person
def mutate(root, info, name):
return Person(name=name)
Then, if we query (``schema.execute(query_str)``) the following:
.. code::
mutation myFirstMutation {
createPerson(name:"Peter") {
name
__typename
}
}
We should receive:
.. code:: json
{
"createPerson": {
"name": "Peter",
"__typename": "Person"
}
}