File: input-types.md

package info (click to toggle)
strawberry-graphql 0.306.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 18,176 kB
  • sloc: javascript: 178,052; python: 65,643; sh: 33; makefile: 25
file content (179 lines) | stat: -rw-r--r-- 3,875 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
---
title: Input types
---

# Input types

In addition to [object types](./object-types) GraphQL also supports input types.
While being similar to object types, they are better suited for input data as
they limit the kind of types you can use for fields.

This is how the
[GraphQL spec defines the difference between object types and input types](https://spec.graphql.org/June2018/#sec-Input-Objects):

> The GraphQL Object type (ObjectTypeDefinition)... is inappropriate for re‐use
> (as input), because Object types can contain fields that define arguments or
> contain references to interfaces and unions, neither of which is appropriate
> for use as an input argument. For this reason, input objects have a separate
> type in the system.

## Defining input types

In Strawberry, you can define input types by using the `@strawberry.input`
decorator, like this:

<CodeGrid>

```python
import strawberry


@strawberry.input
class Point2D:
    x: float
    y: float
```

```graphql
input Point2D {
  x: Float!
  y: Float!
}
```

</CodeGrid>

Then you can use input types as argument for your fields or mutations:

```python
import strawberry


@strawberry.type
class Mutation:
    @strawberry.mutation
    def store_point(self, a: Point2D) -> bool:
        return True
```

If you want to include optional arguments, you need to provide them with a
default. For example if we want to expand on the above example to allow optional
labeling of our point we could do:

<CodeGrid>

```python
import strawberry
from typing import Optional


@strawberry.input
class Point2D:
    x: float
    y: float
    label: Optional[str] = None
```

```graphql
type Point2D {
    x: Float!
    y: Float!
    label: String = null
}
```

</CodeGrid>

When you need to distinguish between a field being set to `null` versus being
completely absent (common in update operations), you can use `strawberry.Maybe`.
See the [Maybe documentation](./maybe.md) for comprehensive examples and usage
patterns.

## API

`@strawberry.input(name: str = None, description: str = None)`

Creates an input type from a class definition.

- `name`: if set this will be the GraphQL name, otherwise the GraphQL will be
  generated by camel-casing the name of the class.
- `description`: this is the GraphQL description that will be returned when
  introspecting the schema or when navigating the schema using GraphiQL.

## One Of Input Types

Strawberry also supports defining input types that can have only one field set.
This is based on the
[OneOf Input Objects RFC](https://github.com/graphql/graphql-spec/pull/825)

To define a one of input type you can use the `one_of` flag on the
`@strawberry.input` decorator:

<CodeGrid>

```python
import strawberry


@strawberry.input(one_of=True)
class SearchBy:
    name: strawberry.Maybe[str]
    email: strawberry.Maybe[str]
```

```graphql
input SearchBy @oneOf {
  name: String
  email: String
}
```

</CodeGrid>

<Note>

OneOf inputs use `strawberry.Maybe` to distinguish between fields that are
explicitly not provided versus those that might be set to null. See the
[Maybe documentation](./maybe.md) for more details on this usage pattern.

</Note>

## Deprecating fields

Fields can be deprecated using the argument `deprecation_reason`.

<Note>

This does not prevent the field from being used, it's only for documentation.
See:
[GraphQL field deprecation](https://spec.graphql.org/June2018/#sec-Field-Deprecation).

</Note>

<CodeGrid>

```python
import strawberry
from typing import Optional


@strawberry.input
class Point2D:
    x: float
    y: float
    z: Optional[float] = strawberry.field(
        deprecation_reason="3D coordinates are deprecated"
    )
    label: Optional[str] = None
```

```graphql
input Point2D {
  x: Float!
  y: Float!
  z: Float @deprecated(reason: "3D coordinates are deprecated")
  label: String = null
}
```

</CodeGrid>