This repository has been archived by the owner on Apr 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTestSchema.fs
229 lines (200 loc) · 8.7 KB
/
TestSchema.fs
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
namespace UnitTest
open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Types
#nowarn "40"
type Episode =
| NewHope = 1
| Empire = 2
| Jedi = 3
type Human =
{ Id : string
Name : string option
Friends : string list
AppearsIn : Episode list
HomePlanet : string option }
type Droid =
{ Id : string
Name : string option
Friends : string list
AppearsIn : Episode list
PrimaryFunction : string option }
type Planet =
{ Id : string
Name : string option
mutable IsMoon : bool option }
member x.SetMoon b =
x.IsMoon <- b
x
type Root =
{ RequestId: string }
type Character =
| Human of Human
| Droid of Droid
module TestSchema =
let humans =
[ { Id = "1000"
Name = Some "Luke Skywalker"
Friends = [ "1002"; "1003"; "2000"; "2001" ]
AppearsIn = [ Episode.NewHope; Episode.Empire; Episode.Jedi ]
HomePlanet = Some "Tatooine" }
{ Id = "1001"
Name = Some "Darth Vader"
Friends = [ "1004" ]
AppearsIn = [ Episode.NewHope; Episode.Empire; Episode.Jedi ]
HomePlanet = Some "Tatooine" }
{ Id = "1002"
Name = Some "Han Solo"
Friends = [ "1000"; "1003"; "2001" ]
AppearsIn = [ Episode.NewHope; Episode.Empire; Episode.Jedi ]
HomePlanet = None }
{ Id = "1003"
Name = Some "Leia Organa"
Friends = [ "1000"; "1002"; "2000"; "2001" ]
AppearsIn = [ Episode.NewHope; Episode.Empire; Episode.Jedi ]
HomePlanet = Some "Alderaan" }
{ Id = "1004"
Name = Some "Wilhuff Tarkin"
Friends = [ "1001" ]
AppearsIn = [ Episode.NewHope ]
HomePlanet = None } ]
let droids =
[ { Id = "2000"
Name = Some "C-3PO"
Friends = [ "1000"; "1002"; "1003"; "2001" ]
AppearsIn = [ Episode.NewHope; Episode.Empire; Episode.Jedi ]
PrimaryFunction = Some "Protocol" }
{ Id = "2001"
Name = Some "R2-D2"
Friends = [ "1000"; "1002"; "1003" ]
AppearsIn = [ Episode.NewHope; Episode.Empire; Episode.Jedi ]
PrimaryFunction = Some "Astromech" } ]
let planets =
[ { Id = "1"
Name = Some "Tatooine"
IsMoon = Some false}
{ Id = "2"
Name = Some "Endor"
IsMoon = Some true}
{ Id = "3"
Name = Some "Death Star"
IsMoon = Some false}]
let getHuman id =
humans |> List.tryFind (fun h -> h.Id = id)
let getDroid id =
droids |> List.tryFind (fun d -> d.Id = id)
let getPlanet id =
planets |> List.tryFind (fun p -> p.Id = id)
let characters =
(humans |> List.map Human) @ (droids |> List.map Droid)
let matchesId id = function
| Human h -> h.Id = id
| Droid d -> d.Id = id
let getCharacter id =
characters |> List.tryFind (matchesId id)
let EpisodeType =
Define.Enum(
name = "Episode",
description = "One of the films in the Star Wars Trilogy.",
options = [
Define.EnumValue("NewHope", Episode.NewHope, "Released in 1977.")
Define.EnumValue("Empire", Episode.Empire, "Released in 1980.")
Define.EnumValue("Jedi", Episode.Jedi, "Released in 1983.") ])
let rec CharacterType =
Define.Union(
name = "Character",
description = "A character in the Star Wars Trilogy.",
options = [ HumanType; DroidType ],
resolveValue = (fun o ->
match o with
| Human h -> box h
| Droid d -> upcast d),
resolveType = (fun o ->
match o with
| Human _ -> upcast HumanType
| Droid _ -> upcast DroidType))
and HumanType : ObjectDef<Human> =
Define.Object<Human>(
name = "Human",
description = "A humanoid creature in the Star Wars universe.",
isTypeOf = (fun o -> o :? Human),
fieldsFn = fun () ->
[
Define.Field("id", String, "The id of the human.", fun _ (h : Human) -> h.Id)
Define.Field("name", Nullable String, "The name of the human.", fun _ (h : Human) -> h.Name)
Define.Field("friends", ListOf (Nullable CharacterType), "The friends of the human, or an empty list if they have none.",
fun _ (h : Human) -> h.Friends |> List.map getCharacter |> List.toSeq)
Define.Field("appearsIn", ListOf EpisodeType, "Which movies they appear in.", fun _ (h : Human) -> h.AppearsIn)
Define.Field("homePlanet", Nullable String, "The home planet of the human, or null if unknown.", fun _ h -> h.HomePlanet)
])
and DroidType =
Define.Object<Droid>(
name = "Droid",
description = "A mechanical creature in the Star Wars universe.",
isTypeOf = (fun o -> o :? Droid),
fieldsFn = fun () ->
[
Define.Field("id", String, "The id of the droid.", fun _ (d : Droid) -> d.Id)
Define.Field("name", Nullable String, "The name of the Droid.", fun _ (d : Droid) -> d.Name)
Define.Field("friends", ListOf (Nullable CharacterType), "The friends of the Droid, or an empty list if they have none.",
fun _ (d : Droid) -> d.Friends |> List.map getCharacter |> List.toSeq)
Define.Field("appearsIn", ListOf EpisodeType, "Which movies they appear in.", fun _ d -> d.AppearsIn)
Define.Field("primaryFunction", Nullable String, "The primary function of the droid.", fun _ d -> d.PrimaryFunction)
])
and PlanetType =
Define.Object<Planet>(
name = "Planet",
description = "A planet in the Star Wars universe.",
isTypeOf = (fun o -> o :? Planet),
fieldsFn = fun () ->
[
Define.Field("id", String, "The id of the planet", fun _ p -> p.Id)
Define.Field("name", Nullable String, "The name of the planet.", fun _ p -> p.Name)
Define.Field("isMoon", Nullable Boolean, "Is that a moon?", fun _ p -> p.IsMoon)
])
and RootType =
Define.Object<Root>(
name = "Root",
description = "The Root type to be passed to all our resolvers.",
isTypeOf = (fun o -> o :? Root),
fieldsFn = fun () ->
[
Define.Field("requestId", String, "The ID of the client.", fun _ (r : Root) -> r.RequestId)
])
let Query =
Define.Object<Root>(
name = "Query",
fields = [
Define.Field("hero", Nullable HumanType, "Gets human hero", [ Define.Input("id", String) ], fun ctx _ -> getHuman (ctx.Arg("id")))
Define.Field("droid", Nullable DroidType, "Gets droid", [ Define.Input("id", String) ], fun ctx _ -> getDroid (ctx.Arg("id")))
Define.Field("planet", Nullable PlanetType, "Gets planet", [ Define.Input("id", String) ], fun ctx _ -> getPlanet (ctx.Arg("id")))
Define.Field("characters", ListOf CharacterType, "Gets characters", fun _ _ -> characters) ])
let Subscription =
Define.SubscriptionObject<Root>(
name = "Subscription",
fields = [
Define.SubscriptionField(
"watchMoon",
RootType,
PlanetType,
"Watches to see if a planet is a moon.",
[ Define.Input("id", String) ],
(fun ctx _ p -> if ctx.Arg("id") = p.Id then Some p else None)) ])
let schemaConfig = SchemaConfig.Default
let Mutation =
Define.Object<Root>(
name = "Mutation",
fields = [
Define.Field(
"setMoon",
Nullable PlanetType,
"Defines if a planet is actually a moon or not.",
[ Define.Input("id", String); Define.Input("isMoon", Boolean) ],
fun ctx _ ->
getPlanet (ctx.Arg("id"))
|> Option.map (fun x ->
x.SetMoon(Some(ctx.Arg("isMoon"))) |> ignore
schemaConfig.SubscriptionProvider.Publish<Planet> "watchMoon" x
schemaConfig.LiveFieldSubscriptionProvider.Publish<Planet> "Planet" "isMoon" x
x))])
let schema : ISchema<Root> = upcast Schema(Query, Mutation, Subscription, schemaConfig)
let executor = Executor(schema, [])