File: mutations.rst

package info (click to toggle)
python-graphene 3.4.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,120 kB
  • sloc: python: 8,935; makefile: 214; sh: 18
file content (183 lines) | stat: -rw-r--r-- 4,275 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
Mutations
=========

A Mutation is a special ObjectType that also defines an Input.

Quick example
-------------

This example defines a Mutation:

.. code:: python

    import graphene

    class CreatePerson(graphene.Mutation):
        class Arguments:
            name = graphene.String()

        ok = graphene.Boolean()
        person = graphene.Field(lambda: Person)

        def mutate(root, info, name):
            person = Person(name=name)
            ok = True
            return CreatePerson(person=person, ok=ok)

**person** and **ok** are the output fields of the Mutation when it is
resolved.

**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()
        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:

.. 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):
        name = graphene.String(required=True)
        age = graphene.Int(required=True)

    class CreatePerson(graphene.Mutation):
        class Arguments:
            person_data = PersonInput(required=True)

        person = graphene.Field(Person)

        def mutate(root, info, person_data=None):
            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 {
                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()
        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)``) with the following:

.. code::

    mutation myFirstMutation {
        createPerson(name:"Peter") {
            name
            __typename
        }
    }

We should receive:

.. code:: json

    {
        "createPerson": {
            "name": "Peter",
            "__typename": "Person"
        }
    }