Skip to content

Commit 6e551ec

Browse files
Updated documentation on input fields. (#41)
* Clarified the usage of [Required] on input object fields.
1 parent f54a0bc commit 6e551ec

File tree

1 file changed

+66
-53
lines changed

1 file changed

+66
-53
lines changed

docs/types/input-objects.md

Lines changed: 66 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -122,48 +122,6 @@ input Input_Donut {
122122
}
123123
```
124124
125-
126-
## Required Fields And Default Values
127-
Add `[Required]` (from System.ComponentModel) to any property to force a user to supply the field in a query document.
128-
129-
Any non-required field will automatically be assigned a default value if not supplied. This default value is equivilant to the property value of the object when its instantiated via its public, parameterless constructor.
130-
131-
132-
```csharp title="Add the Required attribute for force a query to define a value"
133-
public class Donut
134-
{
135-
public Donut()
136-
{
137-
// set custom defaults if needed
138-
this.Type = DonutType.Frosted;
139-
this.Price = 2.99;
140-
this.IsAvailable = true;
141-
}
142-
143-
[Required]
144-
public string Name { get; set; }
145-
146-
public int Id { get; set; }
147-
public DonutType Type { get; set; }
148-
public Bakery Bakery { get;set; }
149-
public decimal Price { get; set; }
150-
public bool IsAvailable { get; set; }
151-
}
152-
```
153-
154-
```graphql title="Donut Type Definition"
155-
# No Default Value on Name
156-
input Input_Donut {
157-
name: String
158-
id: Int! = 0
159-
type: DonutType! = FROSTED
160-
bakery: Input_Bakery = null
161-
price: Decimal! = 2.99
162-
isAvailable: Boolean! = true
163-
}
164-
```
165-
166-
167125
## Non-Nullability
168126
By default, all properties that are reference types (i.e. classes) are nullable and all value types (primatives, structs etc.) are non-nullable
169127
@@ -190,6 +148,8 @@ public class Donut
190148
{
191149
public Donut()
192150
{
151+
// we must supply a non-null default value
152+
// for a non-nullable field
193153
this.Recipe = new Recipe("Flour, Sugar, Salt");
194154
}
195155
@@ -201,42 +161,95 @@ public class Donut
201161
202162
```graphql title="Input Donut Definition"
203163
input Input_Donut {
204-
recipe: Input_Recipe! = {Ingredients : "Flour, Sugar, Salt" }
164+
recipe: Input_Recipe! = {ingredients : "Flour, Sugar, Salt" }
205165
quantity: Int! = 0
206166
}
207167
```
208168
209169
:::info Did You Notice?
210170
We assigned a recipe in the class's constructor to use as the default value.
211171
212-
Any non-nullable field, that does not have the `[Required]` attribute, MUST have a default value assigned to it that is not `null`.
213-
214-
A `GraphTypeDeclarationException` will be thrown at startup if this is not the case.
172+
Any non-nullable field, that does not have the `[Required]` attribute (see below), MUST have a default value assigned to it that is not `null`. A `GraphTypeDeclarationException` will be thrown at startup if this is not the case.
215173
:::
216174
217-
#### Combine Non-Null and [Required]
218-
Combine the [Required] attribute with a custom type expression to force a user to supply a non-null value for the field on a query document.
219175
220-
```csharp title="Force Owner to be non-null And Required"
221-
public class Bakery
176+
## Required Fields And Default Values
177+
Add `[Required]` (from System.ComponentModel) to any property to force a user to supply the field in a query document.
178+
179+
Any non-required field will automatically be assigned a default value if not supplied on a query. This default value is equivilant to the property value of the object when its instantiated via its public, parameterless constructor.
180+
181+
```csharp title="Add the Required attribute for force a query to define a value"
182+
public class Donut
222183
{
223-
public Bakery()
184+
public Donut()
224185
{
225-
}
186+
// set custom defaults if needed
187+
this.Type = DonutType.Frosted;
188+
this.IsAvailable = true;
189+
}
190+
191+
[Required]
192+
public int Id { get; set; }
193+
194+
public string Name { get; set; }
195+
public DonutType Type { get; set; }
196+
public Bakery Bakery { get;set; }
197+
public bool IsAvailable { get; set; }
198+
public int SkuNumber { get; set; }
199+
}
200+
```
201+
202+
```graphql title="Donut Type Definition"
203+
input Input_Donut {
204+
id: Int! # No Default Value on Id
205+
name: String = null
206+
type: DonutType! = FROSTED
207+
bakery: Input_Bakery = null
208+
isAvailable: Boolean! = true
209+
skuNumber: Int! = 0
210+
}
211+
```
212+
213+
### Nullable Fields are Never Required
214+
By Definition (spec § [5.6.4](https://spec.graphql.org/October2021/#sec-Input-Object-Required-Fields)), a nullable field without a
215+
declared default value is still considered optional and does not need to be supplied. That is to say that if a query does not include a field that is nullable, it will default to `null` regardless of the use of the `[Required]` attribute.
216+
217+
These two property declarations for an input object are identical as far as graphql is concerned:
218+
219+
```csharp title='Example Input object Fields'
220+
public InputEmployee
221+
{
222+
public string FirstName { get; set; }
226223
224+
[Required]
225+
public string LastName { get; set; }
226+
}
227+
```
228+
229+
Both `FirstName` and `LastName` are of type `string`, which is nullable. GraphQL will ignore the required attribute and still allow a query to process even if neither value is supplied on a query.
230+
231+
### Required Reference Types
232+
Combine the [Required] attribute with a non-nullable type expression to force an otherwise nullable field to be required.
233+
234+
```csharp title="Force Owner to be non-null And Required"
235+
public class Bakery
236+
{
227237
[Required]
228238
[GraphField(TypeExpression = "Type!")]
229239
public Person Owner { get; set; }
230240
}
231241
```
232242
233243
```graphql title="Donut Type Definition"
234-
# No Default Value is supplied. owner must be supplied on a query
244+
# No Default Value is supplied.
245+
# the 'owner' must be supplied on a query
235246
input Input_Bakery {
236247
owner: Input_Person!
237248
}
238249
```
239250
251+
`Owner` is of type Person, which is a reference type, which is nullable by default. By augmenting its type expression to be non-null and adding the `[Required]` attribute graphql will not supply a default value require it to be supplied on a query.
252+
240253
## Enum Fields and Coercability
241254
242255
Any default value declared for an input field must be coercible by its target graph type in the target schema. Because of this there is a small got'cha situation with enum values.

0 commit comments

Comments
 (0)