Created
April 15, 2016 17:09
-
-
Save Horusiath/0770c470fd9fb8dd5c2119c33bdbdf9f to your computer and use it in GitHub Desktop.
New API example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// These are all of the possible kinds of types | |
type GraphQLType = | |
interface | |
end | |
/// These types may be used as input types for arguments and directives | |
and InputType<'Inner> = | |
interface | |
end | |
/// These types may be used as output types as the result of fields | |
and OutputType<'Inner> = | |
interface | |
end | |
/// These types may describe types which may be leaf values | |
and LeafType = | |
interface | |
end | |
/// These types may describe the parent context of a selection set | |
and CompositeType = | |
interface | |
end | |
/// These types may describe the parent context of a selection set | |
and AbstractType<'Inner> = | |
interface | |
abstract ResolveType : obj -> ResolveInfo -> ObjectType<'Inner> option | |
end | |
/// These types can all accept null as a value | |
and NullableType = | |
interface | |
end | |
/// These named types do not include modifiers like List or NonNull | |
and NamedType = | |
interface | |
abstract Name : string | |
end | |
and ScalarType<'Inner> = | |
interface | |
inherit GraphQLType | |
inherit InputType<'Inner> | |
inherit OutputType<'Inner> | |
inherit LeafType | |
inherit NullableType | |
inherit NamedType | |
abstract Serialize : obj -> 'Inner option | |
abstract ParseLiteral : Value -> 'Inner option | |
end | |
and EnumType = | |
interface | |
inherit GraphQLType | |
inherit InputType<string> | |
inherit OutputType<string> | |
inherit LeafType | |
inherit NullableType | |
inherit NamedType | |
abstract Values : Map<string, EnumValueDefinition> | |
abstract Serialize : obj -> 'Inner option | |
abstract ParseLiteral : Value -> 'Inner option | |
end | |
and EnumValueDefinition = | |
{ Name : string | |
Description : string option | |
Value : obj } | |
and ObjectType<'Inner> = | |
interface | |
inherit GraphQLType | |
inherit OutputType<'Inner> | |
inherit CompositeType | |
inherit NullableType | |
inherit NamedType | |
abstract IsTypeOf : obj -> ResolveInfo -> bool | |
abstract Fields : Map<string, FieldDefinition<'Inner>> | |
abstract Interfaces : InterfaceType<obj> list | |
end | |
and InterfaceType<'Inner> = | |
interface | |
inherit GraphQLType | |
inherit OutputType<'Inner> | |
inherit CompositeType | |
inherit AbstractType<'Inner> | |
inherit NullableType | |
inherit NamedType | |
abstract Fields : Map<string, FieldDefinition<'Inner>> | |
end | |
and UnionType<'Inner> = | |
interface | |
inherit GraphQLType | |
inherit OutputType<'Inner> | |
inherit CompositeType | |
inherit AbstractType<'Inner> | |
inherit NullableType | |
inherit NamedType | |
abstract Types : ObjectType<'Inner> list | |
end | |
and InputObjectType<'Inner> = | |
interface | |
inherit GraphQLType | |
inherit InputType<'Inner> | |
inherit OutputType<'Inner> | |
inherit NullableType | |
inherit NamedType | |
abstract Fields : Map<string, FieldDefinition<'Inner>> | |
end | |
and ListType<'Inner when 'Inner :> GraphQLType> = | |
interface | |
inherit GraphQLType | |
inherit InputType<'Inner> | |
inherit OutputType<'Inner> | |
inherit NullableType | |
end | |
and NonNullType<'Inner when 'Inner :> NullableType> = | |
interface | |
inherit GraphQLType | |
inherit InputType<'Inner> | |
end | |
and FieldDefinition<'Inner> = | |
interface | |
abstract Name : string | |
abstract Args : ArgumentDefinition array | |
end | |
and ArgumentDefinition = | |
{ Name : string | |
Type : InputType | |
DefaultType : obj option | |
Description : string option } | |
and FieldDefinition<'Inner, 'Val> = | |
interface | |
abstract Type : OutputType<'Val> | |
end | |
and FieldDefinitionConfig<'Inner, 'Val, 'Args> = | |
{ Name : string | |
Description : string option | |
Type : OutputType<'Val> | |
Args : ArgumentDefinition array | |
DeprecationReason : string option | |
Resolve : 'Inner -> 'Args -> ResolveInfo -> 'Val } | |
interface FieldDefinition<'Inner> with | |
member x.Name = x.Name | |
member x.Args = x.Args | |
interface FieldDefinition<'Inner, 'Val> with | |
member x.Type = x.Type | |
and ResolveInfo = | |
{ FieldName : string | |
Fields : Field list | |
ParentType : CompositeType | |
Schema : obj | |
Fragments : Map<string, FragmentDefinition> | |
RootValue : obj | |
Operation : OperationDefinition | |
Variables : Map<string, obj> } | |
type ScalarTypeConfig<'Inner> = | |
{ Name : string | |
Description : string option | |
Serialize : obj -> 'Inner option | |
ParseLiteral : Value -> 'Inner option } | |
interface ScalarType<'Inner> with | |
member x.Name = x.Name | |
member x.ParseLiteral(ast) = x.ParseLiteral ast | |
member x.Serialize(o) = x.Serialize o | |
type EnumTypeConfig = | |
{ Name : string | |
Description : string option | |
Values : EnumValueDefinition list } | |
interface EnumType with | |
member x.Name = x.Name | |
member x.ParseLiteral(ast) = failwith "Not implemented yet" | |
member x.Serialize(arg1) = failwith "Not implemented yet" | |
member x.Values = | |
x.Values | |
|> List.map (fun x -> (x.Name, x)) | |
|> Map.ofList | |
type ObjectTypeConfig<'Inner> = | |
{ Name : string | |
Description : string option | |
IsTypeOf : (obj -> ResolveInfo -> bool) option | |
Interfaces : InterfaceType<obj> list | |
Fields : FieldDefinition<'Inner> list } | |
interface ObjectType<'Inner> with | |
member x.Fields = | |
x.Fields | |
|> List.map (fun x -> (x.Name, x)) | |
|> Map.ofList | |
member x.Interfaces = x.Interfaces | |
member x.IsTypeOf value info = | |
match x.IsTypeOf with | |
| Some resolver -> resolver value info | |
| None -> value :? 'Inner | |
member x.Name = x.Name | |
type InterfaceTypeConfig<'Inner> = | |
{ Name : string | |
Description : string option | |
ResolveType : (obj -> ResolveInfo -> ObjectType<'Inner> option) option | |
Fields : FieldDefinition<'Inner> list } | |
interface InterfaceType<'Inner> with | |
member x.Fields = | |
x.Fields | |
|> List.map (fun x -> (x.Name, x)) | |
|> Map.ofList | |
member x.ResolveType value info = | |
match x.ResolveType with | |
| Some resolver -> resolver value info | |
| None -> None | |
member x.Name = x.Name | |
type UnionTypeConfig<'Inner> = | |
{ Name : string | |
Description : string option | |
ResolveType : (obj -> ResolveInfo -> ObjectType<'Inner> option) option | |
Types : ObjectType<'Inner> list } | |
interface UnionType<'Inner> with | |
member x.Types = x.Types | |
member x.ResolveType value info = | |
match x.ResolveType with | |
| Some resolver -> resolver value info | |
| None -> None | |
member x.Name = x.Name | |
module Mod = | |
// helper func for object type definitions | |
let objdef<'t> (name : string) (fields : FieldDefinition<'t> list) : ObjectType<'t> = | |
let o = | |
{ Name = name | |
Description = None | |
Interfaces = [] | |
IsTypeOf = Some(fun o info -> o :? 't) | |
Fields = fields } | |
o :> ObjectType<'t> | |
// helper func for field definitions | |
let field (name : string) (typedef : #OutputType<'v>) (resolve : 't -> 'a -> ResolveInfo -> 'v) = | |
let f = | |
{ Name = name | |
Description = None | |
Type = typedef | |
Args = [||] | |
DeprecationReason = None | |
Resolve = resolve } | |
f | |
// helper func for scalar types definitions | |
let scalar name serialize parse = | |
let s = | |
{ Name = name | |
Description = None | |
Serialize = serialize | |
ParseLiteral = parse } | |
s :> ScalarType<'t> | |
// let's start with defining two scalar types for int and string | |
// second func is not implemented | |
let Int = scalar "Int" (fun o -> Some(o :?> int)) (fun v -> Some 0) | |
let String = scalar "String" (fun o -> Some(o :?> string)) (fun v -> Some "") | |
// define custom types - this example shows how nested types can be defined | |
// using GraphQL object types | |
type Deeper = | |
{ z : int } | |
type Record = | |
{ x : int | |
y : string | |
deep : Deeper } | |
// first we define object type for nested record... | |
let DeeperDef = objdef<Deeper> "Deeper" [ field "z" Int (fun deeper _ _ -> deeper.z) ] | |
// ...then for the top-level record | |
// everything is type safe - i.e. unlike previous API, | |
// you cannot define field x with graphQL type String, cause String is Scalar type constrained to .NET string type | |
// also 3rd param (resolve function) can infer all input and output types, which was not checked previously | |
let RecordDef = | |
objdef<Record> "Record" [ field "x" Int (fun record _ _ -> record.x) | |
field "y" String (fun record _ _ -> record.y) | |
field "deeper" DeeperDef (fun record _ _ -> record.deep) ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment