-
Notifications
You must be signed in to change notification settings - Fork 74
/
standard_features.fsx
111 lines (89 loc) · 5.24 KB
/
standard_features.fsx
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
// Uncomment those to use build script client assembly
//#r "../../bin/FSharp.Data.GraphQL.Client/net461/FSharp.Data.GraphQL.Client.dll"
//#r "../../bin/FSharp.Data.GraphQL.Shared/net461/FSharp.Data.GraphQL.Shared.dll"
// Uncomment those to use build script client assembly using netstandard2.0
//#r "../../bin/FSharp.Data.GraphQL.Shared/netstandard2.0/FSharp.Data.GraphQL.Shared.dll"
//#r "../../bin/FSharp.Data.GraphQL.Client/netstandard2.0/netstandard.dll"
//#r "../../bin/FSharp.Data.GraphQL.Client/netstandard2.0/FSharp.Data.GraphQL.Client.dll"
// Uncomment those to use dotnet build command for the client assembly
// #r "../../src/FSharp.Data.GraphQL.Shared/bin/Debug/net461/FSharp.Data.GraphQL.Shared.dll"
// #r "../../src/FSharp.Data.GraphQL.Client/bin/Debug/net461/FSharp.Data.GraphQL.Client.dll"
//Uncomment those to use dotnet build command for the client assembly using netstandard2.0
#r "../../src/FSharp.Data.GraphQL.Shared/bin/Debug/netstandard2.0/FSharp.Data.GraphQL.Shared.dll"
#r "../../src/FSharp.Data.GraphQL.Client/bin/Debug/netstandard2.0/netstandard.dll"
#r "../../src/FSharp.Data.GraphQL.Client/bin/Debug/netstandard2.0/FSharp.Data.GraphQL.Client.dll"
open FSharp.Data.GraphQL
// The URL here is for design time purposes.
// It connects to the server to be able to map its schema.
type MyProvider = GraphQLProvider<"http://localhost:8086">
// You can also provide the introspection schema yourself if you can't access the server
// at design time. Just provide a file in the path of the project or a literal containing
// the introspection query result.
// WARNING: the introspection query result must contain all fields requested by the
// standard introspection query string in FSharp.Data.GraphQL.IntrospectionQuery.IntrospectionQuery (FSharp.Data.GraphQL.Shared Assembly).
//type MyProvider = GraphQLProvider<"swapi_schema.json">
// The operation method can be used to make queries, mutations, and subscriptions.
// Although subscription operations can be created, the client provider still
// does not work with web sockets - only the immediate response will be known.
let operation =
MyProvider.Operation<"""query q {
hero (id: "1000") {
name
appearsIn
homePlanet
friends {
... on Human {
name
homePlanet
}
... on Droid {
name
primaryFunction
}
}
}
}""">
()
// To use different server address or custom HTTP headers at runtime, you need to specify a GraphQLProviderRuntimeContext.
//let runtimeContext = MyProvider.GetContext(serverUrl = "http://localhost:8086")
// You can specify a connection factory to manage your connection lifecycle if you want.
let connection = new GraphQLClientConnection ()
let runtimeContext = MyProvider.GetContext (serverUrl = "http://localhost:8086", connectionFactory = fun () -> connection)
// To run an operation, you just need to call the Run or AsyncRun method.
let result = operation.Run (runtimeContext)
//let result = operation.AsyncRun() |> Async.RunSynchronously
// If the operation runs without any error, result data will be on the Data property.
let data = result.Data
// If the operation does not have a Data (None), it could be failed on the server and the errors are mapped
// to the Error property.
let errors = result.Errors
// Custom fields are returned here (for example, documentId on our sample Giraffe Server.)
let customData = result.CustomData
// Query result objects have pretty-printing and structural equality.
printfn "Data: %A\n" data
printfn "Errors: %A\n" errors
printfn "Custom data: %A\n" customData
let hero = data.Value.Hero.Value
// GraphQL enum types are essentially strings, and here they are mapped to
// custom objects with string values inside. Each enum value does have an static
// instance of itself, and does have structural equality against other enum types.
// However, they are not classic CLR enum types.
if hero.AppearsIn |> Array.exists (fun x -> x = MyProvider.Types.Episode.Empire)
then printfn "Hero appears in Empire episode!\n"
else printfn "Hero does not appear in Empire episode!\n"
let friends = hero.Friends |> Array.choose id
// When we have interfaces or union types in the GraphQL schema, they are mapped as
// Inherited objects in the client. However, as the type provider uses erased types,
// we can't pattern match them by classic pattern matching. Instead, we use the following
// methods of types generated by GraphQL union or interface types:
// This will produce an error. Not all friends are droids!
//let thisWillProduceAnError = friends |> Array.map (fun x -> x.AsDroid())
// We can easily filter friends by using "TryAs" methods.
let humanFriends = friends |> Array.choose (fun x -> x.TryAsHuman ())
let droidFriends = friends |> Array.choose (fun x -> x.TryAsDroid ())
// We can also use "Is" version methods to do some custom matching.
let humanFriendsCount = friends |> Array.map (fun x -> if x.IsHuman() then 1 else 0) |> Array.reduce (+)
let droidFriendsCount = friends |> Array.map (fun x -> if x.IsDroid() then 1 else 0) |> Array.reduce (+)
printfn "Hero friends (%i): %A\n" friends.Length friends
printfn "Hero human friends (%i): %A\n" humanFriendsCount humanFriends
printfn "Hero droid friends (%i): %A\n" droidFriendsCount droidFriends