You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/type-system.md
+53-15
Original file line number
Diff line number
Diff line change
@@ -7,12 +7,12 @@ Each schema definition requires to have something called *root query* - it's a G
7
7
8
8
GraphQL type system categorizes several custom types, that can be defined by programmer, including:
9
9
10
-
-[Objects](#Defining-an-Object)
11
-
-[Interfaces](#Defining-an-Interface)
12
-
-[Unions](#Defining-a-Union)
13
-
-[Enums](#Defining-an-Enum)
14
-
-[Scalars](#Defining-a-Scalar)
15
-
-[InputObjects](#Defining-an-Input-Object)
10
+
-[Objects](#defining-an-object)
11
+
-[Interfaces](#defining-an-interface)
12
+
-[Unions](#defining-a-union)
13
+
-[Enums](#defining-an-enum)
14
+
-[Scalars](#defining-a-scalar)
15
+
-[InputObjects](#defining-an-input-object)
16
16
17
17
Beside them, FSharp.Data.GraphQL defines two others:
18
18
@@ -150,7 +150,8 @@ type Ord =
150
150
let Ord = Define.Enum("Ord", [
151
151
Define.EnumValue("Lesser", Ord.Lt)
152
152
Define.EnumValue("Equal", Ord.Eq)
153
-
Define.EnumValue("Greater", Ord.Greater) ])
153
+
Define.EnumValue("Greater", Ord.Greater)
154
+
])
154
155
```
155
156
156
157
The major difference from .NET here is that GraphQL expects, that enum values are serialized as **strings**. Therefore, upon serialization, given enum value will be projected using `ToString()` method.
@@ -162,24 +163,61 @@ Just like enums, GraphQL scalars are leaf types, that should be able to be seria
162
163
```fsharp
163
164
let Guid = Define.Scalar(
164
165
name = "Guid",
165
-
coerceInput = (fun (StringValue s) -> match Guid.TryParse(s) with true, g -> Some g | false, _ -> None),
166
-
coerceValue = fun v -> match v with | :? Guid g -> Some g | _ -> None)
| Variable e -> e.GetDeserializeError destinationType
177
+
// Handle inline value as AST discriminated union object
178
+
| InlineConstant (StringValue s) ->
179
+
match Guid.TryParse(s) with
180
+
| true, guid -> Ok guid
181
+
| false, _ -> getParseError destinationType s
182
+
| InlineConstant value -> value.GetCoerceError destinationType),
183
+
coerceValue = // Returns Guid option
184
+
fun v -> match v with | :? Guid g -> Some g | _ -> None
185
+
)
167
186
```
168
187
169
-
This examples shows how to create a scalar definition for .NET `Guid` type. It requires two functions to be defines:
188
+
This example shows how to create a scalar definition for the .NET `Guid` type. It requires two functions to be defined:
170
189
171
-
1.`coerceInput` function, which will be used to resolve your scalar value directly from values encoded in GraphQL query string (in this case StringValue is just part of parsed query AST).
172
-
2.`coerceValue` function, which will be used to apply something like "implicit casts" between two .NET types in conflicting cases - like when value is passed in variables query string part - which should be tolerated.
190
+
1.`coerceInput` function, which will be used to resolve your scalar value from a variable or directly from a value encoded in a GraphQL query string (in this case StringValue is just a part of the parsed query AST).
191
+
2.`coerceValue` function, which will return `Some` only if the value falls under the scalar's allowed values range, otherwise `None`. Applied while producing the return object graph from the resolver's output.
173
192
174
193
## Defining an Input Object
175
194
176
-
Just like objects, input objects describe a complex data types - however while Objects are designed to work as **output** types, Input Objects are **input** types only.
195
+
Just like objects, input objects describe a complex data types - however while Objects are designed to work as **output** types, Input Objects are **input** types only.
177
196
178
197
```fsharp
179
198
type CreateAccountData = { Email: string; Password: string }
180
-
let CreateAccountData = Define.InputObject("CreateAccountData", [
199
+
let CreateAccountDataType = Define.InputObject("CreateAccountData", [
181
200
Define.Input("email", String)
182
-
Define.Input("password", String) ])
201
+
Define.Input("password", String)
202
+
])
183
203
```
184
204
185
205
Unlike the objects, you neither define input object field resolver nor provide any arguments for it. They also don't work together with abstract types like interfaces or unions.
206
+
207
+
Validate individual properties at scalar definition level, but use validator to validate the whole input object or several dependant properties like this:
208
+
209
+
```fsharp
210
+
type InputAddress = { Country : string; ZipCode : string; City : string }
0 commit comments