forked from fsprojects/FSharp.Data.GraphQL
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSchema.fs
More file actions
215 lines (192 loc) · 11.3 KB
/
Schema.fs
File metadata and controls
215 lines (192 loc) · 11.3 KB
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
namespace FSharp.Data.GraphQL.Samples.StarWarsApi
open System
open System.Text
open Microsoft.AspNetCore.Http
open Microsoft.Extensions.DependencyInjection
type Root(ctx : HttpContext) =
member _.RequestAborted: System.Threading.CancellationToken = ctx.RequestAborted
member _.ServiceProvider: IServiceProvider = ctx.RequestServices
member root.GetRequiredService<'t>() = root.ServiceProvider.GetRequiredService<'t>()
open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Types
type InputField =
{ String : string
Int : int
StringOption : string option
IntOption : int option
Uri : Uri
Guid : Guid
GuidOption : Guid option }
type Input =
{ Single : InputField option
List : InputField list option }
type InputFile =
{ File : FileData }
type UploadedFile =
{ Name : string
ContentType : string
ContentAsText : string }
type UploadedContentFile =
{ Name : string
ContentAsText : string }
type UploadRequest =
{ Single : FileData
Multiple : FileData list
NullableMultiple : FileData list option
NullableMultipleNullable : FileData option list option }
type UploadResponse =
{ Single : UploadedFile
Multiple : UploadedFile list
NullableMultiple : UploadedFile list option
NullableMultipleNullable : UploadedFile option list option }
module Schema =
let InputFieldType =
Define.InputObject<InputField>(
name = "InputField",
fields =
[ Define.Input("string", StringType, description = "A string value.")
Define.Input("int", IntType, description = "An integer value.")
Define.Input("stringOption", Nullable StringType, description = "A string option value.")
Define.Input("intOption", Nullable IntType, description = "An integer option value.")
Define.Input("uri", UriType, description = "An URI value.")
Define.Input("guid", GuidType, description = "A Guid value.") ])
let InputType =
Define.InputObject<Input>(
name ="Input",
description = "Input object type.",
fields =
[ Define.Input("single", Nullable InputFieldType, description = "A single input field.")
Define.Input("list", Nullable (ListOf InputFieldType), description = "A list of input fields.") ])
let OutputFieldType =
Define.Object<InputField>(
name = "OutputField",
description = "The output for a field input.",
fields =
[ Define.Field("string", StringType, resolve = (fun _ x -> x.String), description = "A string value.")
Define.AutoField("int", IntType, description = "An integer value.")
Define.AutoField("stringOption", Nullable StringType, description = "A string option value.")
Define.AutoField("intOption", Nullable IntType, description = "An integer option value.")
Define.AutoField("uri", UriType, description = "An URI value.")
Define.AutoField("guid", GuidType, description = "A Guid value.")
Define.Field("guidId", IDType, description = "A Guid Id value.", resolve = fun _ o -> o.Guid |> string)
Define.Field("stringId", IDType, description = "A String Id value.", resolve = fun _ o -> o.String)
Define.Field("guidIdOption", Nullable IDType, description = "A Guid Id value.", resolve = fun _ o -> o.GuidOption |> Option.map string)
Define.Field("stringIdOption", Nullable IDType, description = "A String Id value.", resolve = fun _ o -> o.StringOption)
Define.Field("deprecated", StringType, resolve = (fun _ x -> x.String), description = "A string value through a deprecated field.", deprecationReason = "This field is deprecated.", args = []) ])
let UploadedFileType =
Define.Object<UploadedFile>(
name = "UploadedFile",
description = "Contains data of an uploaded file.",
fields =
[ Define.AutoField("name", StringType, description = "The name of the file.")
Define.AutoField("contentType", StringType, description = "The content type of the file.")
Define.AutoField("contentAsText", StringType, description = "The content of the file as text.") ])
let UploadRequestType =
Define.InputObject<UploadRequest>(
name = "UploadRequest",
description = "Request for uploading files in several different forms.",
fields =
[ Define.Input("single", FileType, description = "A single file upload.")
Define.Input("multiple", ListOf FileType, description = "Multiple file uploads.")
Define.Input("nullableMultiple", Nullable (ListOf FileType), description = "Optional list of multiple file uploads.")
Define.Input("nullableMultipleNullable", Nullable (ListOf (Nullable FileType)), description = "Optional list of multiple optional file uploads.") ])
let UploadResponseType =
Define.Object<UploadResponse>(
name = "UploadResponse",
description = "Contains uploaded files of an upload files request.",
fields =
[ Define.AutoField("single", UploadedFileType, description = "A single file upload.")
Define.AutoField("multiple", ListOf UploadedFileType, description = "Multiple file uploads.")
Define.AutoField("nullableMultiple", Nullable (ListOf UploadedFileType), description = "Optional list of multiple file uploads.")
Define.AutoField("nullableMultipleNullable", Nullable (ListOf (Nullable UploadedFileType)), description = "Optional list of multiple optional file uploads.") ])
let OutputType =
Define.Object<Input>(
name = "Output",
description = "The output for an input.",
fields =
[ Define.AutoField("single", Nullable OutputFieldType, description = "A single output field.")
Define.AutoField("list", Nullable (ListOf OutputFieldType), description = "A list of output fields.") ])
let QueryType =
Define.Object<Root>(
name = "Query",
description = "The query type.",
fields =
[ Define.Field(
name = "echo",
typedef = StructNullable OutputType,
description = "Enters an input type and get it back.",
args = [ Define.Input("input", Nullable InputType, description = "The input to be echoed as an output.") ],
resolve = fun ctx _ -> ctx.TryArg("input")) ])
let InputFileObject = Define.InputObject<InputFile>(
name = "InputFile",
fields =
[
Define.Input("file", FileType)
])
let MutationType =
let contentAsText (stream : System.IO.Stream) =
use reader = new System.IO.StreamReader(stream, Encoding.UTF8)
reader.ReadToEnd()
let getFileContent (ctx : ResolveFieldContext) argName =
let inputFile = ctx.Arg<InputFile> argName
let stream = inputFile.File.Stream
use reader = new System.IO.StreamReader(stream, Encoding.UTF8, true)
reader.ReadToEnd()
let mapUploadToOutput (file : FileData) =
{ Name = file.FileName; ContentType = file.ContentType; ContentAsText = contentAsText file.Stream }
let mapUploadRequestToOutput (request : UploadRequest) =
{
Single = mapUploadToOutput request.Single
Multiple = request.Multiple |> List.map mapUploadToOutput
NullableMultiple = request.NullableMultiple |> Option.map (List.map mapUploadToOutput)
NullableMultipleNullable = request.NullableMultipleNullable |> Option.map (List.map (Option.map mapUploadToOutput))
}
Define.Object<Root>(
name = "Mutation",
fields =
[
Define.Field(
name = "singleUpload",
typedef = UploadedFileType,
description = "Uploads a single file to the server and get it back.",
args = [ Define.Input("file", FileType, description = "The file to be uploaded.") ],
resolve = fun ctx _ -> mapUploadToOutput (ctx.Arg("file")))
Define.Field(
name = "nullableSingleUpload",
typedef = StructNullable UploadedFileType,
description = "Uploads (maybe) a single file to the server and get it back (maybe).",
args = [ Define.Input("file", Nullable FileType, description = "The file to be uploaded.") ],
resolve = fun ctx _ -> ctx.TryArg("file") |> ValueOption.map mapUploadToOutput)
Define.Field(
name = "multipleUpload",
typedef = ListOf UploadedFileType,
description = "Uploads a list of files to the server and get them back.",
args = [ Define.Input("files", ListOf FileType, description = "The files to upload.") ],
resolve = fun ctx _ -> ctx.Arg("files") |> List.map mapUploadToOutput)
Define.Field(
name = "nullableMultipleUpload",
typedef = StructNullable (ListOf UploadedFileType),
description = "Uploads (maybe) a list of files to the server and get them back (maybe).",
args = [ Define.Input("files", Nullable (ListOf FileType), description = "The files to upload.") ],
resolve = fun ctx _ -> ctx.TryArg("files") |> ValueOption.map (List.map mapUploadToOutput))
Define.Field(
name = "nullableMultipleNullableUpload",
typedef = StructNullable (ListOf (Nullable UploadedFileType)),
description = "Uploads (maybe) a list of files (maybe) to the server and get them back (maybe).",
args = [ Define.Input("files", Nullable (ListOf (Nullable FileType)), description = "The files to upload.") ],
resolve = fun ctx _ -> ctx.TryArg("files") |> ValueOption.map (List.map (Option.map mapUploadToOutput)))
Define.Field(
name = "uploadRequest",
typedef = UploadResponseType,
description = "Upload several files in different forms.",
args = [ Define.Input("request", UploadRequestType, description = "The request for uploading several files in different forms.") ],
resolve = fun ctx _ -> mapUploadRequestToOutput (ctx.Arg("request")))
Define.Field (
name = "uploadComplex",
typedef = StringType,
description = "",
args = [ Define.Input ("input", InputFileObject) ],
resolve = fun ctx _ -> getFileContent ctx "input")
])
let schema : ISchema<Root> = upcast Schema(QueryType, MutationType)
let executor = Executor(schema)