Skip to content

Commit 36f2500

Browse files
committed
Add __Directive, fix some issues with Type vs. Instance in introspection.
Works on fixing graphql-dotnet#3, graphql-dotnet#4.
1 parent 0250259 commit 36f2500

File tree

12 files changed

+237
-40
lines changed

12 files changed

+237
-40
lines changed

src/GraphQL.Tests/StarWars/StarWarsIntrospectionTests.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ public void allows_querying_the_schema()
177177
var query = @"
178178
query SchemaIntrospectionQuery {
179179
__schema {
180+
types { name, kind }
180181
queryType { name, kind }
181182
mutationType { name }
182183
directives {
@@ -199,5 +200,82 @@ query SchemaIntrospectionQuery {
199200

200201
AssertQuerySuccess(query, expected);
201202
}
203+
204+
[Test]
205+
public void allows_querying_field_args()
206+
{
207+
var query = @"
208+
query SchemaIntrospectionQuery {
209+
__schema {
210+
queryType {
211+
fields {
212+
name
213+
args {
214+
name
215+
description
216+
type {
217+
name
218+
kind
219+
ofType {
220+
name
221+
kind
222+
}
223+
}
224+
defaultValue
225+
}
226+
}
227+
}
228+
}
229+
}
230+
";
231+
var expected = @"{
232+
'__schema': {
233+
'queryType': { 'name':'Query', 'kind': 'OBJECT'},
234+
'mutationType': null,
235+
'directives': [],
236+
}
237+
}";
238+
239+
AssertQuerySuccess(query, expected);
240+
}
241+
242+
[Test]
243+
public void full_schema_query()
244+
{
245+
var query = @"
246+
query SchemaIntrospectionQuery {
247+
__schema {
248+
queryType { name, kind }
249+
types {
250+
kind
251+
name
252+
description
253+
fields {
254+
name
255+
description
256+
type {
257+
name
258+
kind
259+
}
260+
isDeprecated
261+
deprecationReason
262+
}
263+
}
264+
mutationType { name }
265+
directives {
266+
name
267+
description
268+
onOperation
269+
onFragment
270+
onField
271+
}
272+
}
273+
}
274+
";
275+
276+
var expected = "{'__schema':''}";
277+
278+
AssertQuerySuccess(query, expected);
279+
}
202280
}
203281
}

src/GraphQL.Tests/StarWars/StarWarsQuery.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public StarWarsQuery()
1616
arguments: new QueryArguments(
1717
new []
1818
{
19-
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "id" }
19+
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "id", Description = "id of the human" }
2020
}),
2121
resolve: context => data.GetHumanById((string)context.Arguments["id"])
2222
);
@@ -25,7 +25,7 @@ public StarWarsQuery()
2525
arguments: new QueryArguments(
2626
new []
2727
{
28-
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "id" }
28+
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "id", Description = "id of the droid" }
2929
}),
3030
resolve: context => data.GetDroidById((string)context.Arguments["id"])
3131
);

src/GraphQL/GraphQL.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
<Compile Include="Introspection\TypeKind.cs" />
5858
<Compile Include="Introspection\TypeMetaFieldType.cs" />
5959
<Compile Include="Introspection\TypeNameMetaFieldType.cs" />
60+
<Compile Include="Introspection\__Directive.cs" />
6061
<Compile Include="Introspection\__EnumValue.cs" />
6162
<Compile Include="Introspection\__Field.cs" />
6263
<Compile Include="Introspection\__InputValue.cs" />

src/GraphQL/Introspection/SchemaMetaFieldType.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Reflection;
41
using GraphQL.Types;
52

63
namespace GraphQL.Introspection
@@ -35,7 +32,7 @@ public __Schema()
3532
{
3633
return context.Schema.Mutation;
3734
});
38-
Field<NonNullGraphType<ListGraphType<__Type>>>("directives", "A list of all directives supported by this server.", null, context =>
35+
Field<NonNullGraphType<ListGraphType<__Directive>>>("directives", "A list of all directives supported by this server.", null, context =>
3936
{
4037
return context.Schema.Directives;
4138
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Linq;
2+
using GraphQL.Types;
3+
4+
namespace GraphQL.Introspection
5+
{
6+
public class __Directive : ObjectGraphType
7+
{
8+
public __Directive()
9+
{
10+
Name = "__Directive";
11+
Field<NonNullGraphType<StringGraphType>>("name");
12+
Field<StringGraphType>("description");
13+
Field<NonNullGraphType<ListGraphType<NonNullGraphType<__InputValue>>>>("args", resolve: context =>
14+
{
15+
var fieldType = (FieldType) context.Source;
16+
return fieldType.Arguments ?? Enumerable.Empty<QueryArgument>();
17+
});
18+
Field<NonNullGraphType<BooleanGraphType>>("onOperation");
19+
Field<NonNullGraphType<BooleanGraphType>>("onFragment");
20+
Field<NonNullGraphType<BooleanGraphType>>("onField");
21+
}
22+
}
23+
}

src/GraphQL/Introspection/__Field.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
13
using GraphQL.Types;
24

35
namespace GraphQL.Introspection
@@ -13,8 +15,7 @@ public __Field()
1315
context =>
1416
{
1517
var fieldType = (FieldType) context.Source;
16-
// TODO: probably need to format these
17-
return fieldType.Arguments;
18+
return fieldType.Arguments ?? Enumerable.Empty<QueryArgument>();
1819
});
1920
Field<NonNullGraphType<__Type>>("type");
2021
Field<NonNullGraphType<BooleanGraphType>>("isDeprecated", null, null, context =>

src/GraphQL/Introspection/__Type.cs

Lines changed: 113 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,35 @@ public __Type()
1111
Name = "__Type";
1212
Field<NonNullGraphType<__TypeKind>>("kind", null, null, context =>
1313
{
14-
if (context.Source is ScalarGraphType)
14+
if (context.Source is GraphType)
1515
{
16-
return TypeKind.SCALAR;
17-
} else if (context.Source is ObjectGraphType)
18-
{
19-
return TypeKind.OBJECT;
20-
} else if (context.Source is InterfaceGraphType)
21-
{
22-
return TypeKind.INTERFACE;
23-
} else if (context.Source is UnionGraphType)
24-
{
25-
return TypeKind.UNION;
26-
} else if (context.Source is EnumerationGraphType)
27-
{
28-
return TypeKind.ENUM;
29-
} else if (context.Source is InputObjectGraphType)
30-
{
31-
return TypeKind.INPUT_OBJECT;
32-
} else if (context.Source is ListGraphType)
33-
{
34-
return TypeKind.LIST;
35-
} else if (context.Source is NonNullGraphType)
16+
return KindForInstance((GraphType)context.Source);
17+
}
18+
else if (context.Source is Type)
3619
{
37-
return TypeKind.NON_NULL;
20+
return KindForType((Type)context.Source);
3821
}
3922

4023
throw new ExecutionError("Unkown kind of type: {0}".ToFormat(context.Source));
4124
});
42-
Field<StringGraphType>("name");
25+
Field<StringGraphType>("name", resolve: context =>
26+
{
27+
if (context.Source is Type)
28+
{
29+
var type = (Type) context.Source;
30+
31+
if (typeof (NonNullGraphType).IsAssignableFrom(type)
32+
|| typeof (ListGraphType).IsAssignableFrom(type))
33+
{
34+
return null;
35+
}
36+
37+
var resolved = context.Schema.FindType(type);
38+
return resolved.Name;
39+
}
40+
41+
return ((GraphType) context.Source).Name;
42+
});
4343
Field<StringGraphType>("description");
4444
Field<ListGraphType<NonNullGraphType<__Field>>>("fields", null,
4545
new QueryArguments(new[]
@@ -63,12 +63,12 @@ public __Type()
6363

6464
return Enumerable.Empty<FieldType>();
6565
});
66-
Field<ListGraphType<NonNullGraphType<__Type>>>("interfaces", null, null, context =>
66+
Field<ListGraphType<NonNullGraphType<__Type>>>("interfaces", resolve: context =>
6767
{
6868
var type = context.Source as IImplementInterfaces;
6969
return type != null ? type.Interfaces : Enumerable.Empty<Type>();
7070
});
71-
Field<ListGraphType<NonNullGraphType<__Type>>>("possibleTypes", null, null, context =>
71+
Field<ListGraphType<NonNullGraphType<__Type>>>("possibleTypes", resolve: context =>
7272
{
7373
if (context.Source is InterfaceGraphType || context.Source is UnionGraphType)
7474
{
@@ -99,12 +99,98 @@ public __Type()
9999

100100
return Enumerable.Empty<EnumValue>();
101101
});
102-
Field<ListGraphType<NonNullGraphType<__InputValue>>>("inputFields", null, null, context =>
102+
Field<ListGraphType<NonNullGraphType<__InputValue>>>("inputFields", resolve: context =>
103103
{
104104
var type = context.Source as InputObjectGraphType;
105105
return type != null ? type.Fields : Enumerable.Empty<FieldType>();
106106
});
107-
Field<__Type>("ofType");
107+
Field<__Type>("ofType", resolve: context =>
108+
{
109+
if (context.Source is Type)
110+
{
111+
var type = (Type) context.Source;
112+
var genericType = type.GetGenericArguments()[0];
113+
return genericType;
114+
}
115+
116+
return null;
117+
});
118+
}
119+
120+
public TypeKind KindForInstance(GraphType type)
121+
{
122+
if (type is EnumerationGraphType)
123+
{
124+
return TypeKind.ENUM;
125+
}
126+
if (type is ScalarGraphType)
127+
{
128+
return TypeKind.SCALAR;
129+
}
130+
if (type is ObjectGraphType)
131+
{
132+
return TypeKind.OBJECT;
133+
}
134+
if (type is InterfaceGraphType)
135+
{
136+
return TypeKind.INTERFACE;
137+
}
138+
if (type is UnionGraphType)
139+
{
140+
return TypeKind.UNION;
141+
}
142+
if (type is InputObjectGraphType)
143+
{
144+
return TypeKind.INPUT_OBJECT;
145+
}
146+
if (type is ListGraphType)
147+
{
148+
return TypeKind.LIST;
149+
}
150+
if (type is NonNullGraphType)
151+
{
152+
return TypeKind.NON_NULL;
153+
}
154+
155+
throw new ExecutionError("Unkown kind of type: {0}".ToFormat(type));
156+
}
157+
158+
public TypeKind KindForType(Type type)
159+
{
160+
if (typeof(EnumerationGraphType).IsAssignableFrom(type))
161+
{
162+
return TypeKind.ENUM;
163+
}
164+
if (typeof(ScalarGraphType).IsAssignableFrom(type))
165+
{
166+
return TypeKind.SCALAR;
167+
}
168+
if (typeof(ObjectGraphType).IsAssignableFrom(type))
169+
{
170+
return TypeKind.OBJECT;
171+
}
172+
if (typeof(InterfaceGraphType).IsAssignableFrom(type))
173+
{
174+
return TypeKind.INTERFACE;
175+
}
176+
if (typeof(UnionGraphType).IsAssignableFrom(type))
177+
{
178+
return TypeKind.UNION;
179+
}
180+
if (typeof (InputObjectGraphType).IsAssignableFrom(type))
181+
{
182+
return TypeKind.INPUT_OBJECT;
183+
}
184+
if (typeof (ListGraphType).IsAssignableFrom(type))
185+
{
186+
return TypeKind.LIST;
187+
}
188+
if (typeof(NonNullGraphType).IsAssignableFrom(type))
189+
{
190+
return TypeKind.NON_NULL;
191+
}
192+
193+
throw new ExecutionError("Unkown kind of type: {0}".ToFormat(type));
108194
}
109195
}
110196
}

src/GraphQL/Types/GraphType.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public virtual string CollectTypes(TypeCollectionContext context)
4545
}
4646
}
4747

48+
/// <summary>
49+
/// This sucks, find a better way
50+
/// </summary>
4851
public class TypeCollectionContext
4952
{
5053
public TypeCollectionContext(

src/GraphQL/Types/ListGraphType.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ public ListGraphType()
1111
}
1212
}
1313

14-
public class ListGraphType : GraphType
14+
public abstract class ListGraphType : GraphType
1515
{
16-
public ListGraphType(Type type)
16+
protected ListGraphType(Type type)
1717
{
1818
Type = type;
1919
}

src/GraphQL/Types/NonNullGraphType.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ public NonNullGraphType()
1111
}
1212
}
1313

14-
public class NonNullGraphType : GraphType
14+
public abstract class NonNullGraphType : GraphType
1515
{
16-
public NonNullGraphType(Type type)
16+
protected NonNullGraphType(Type type)
1717
{
1818
if (type == typeof (NonNullGraphType))
1919
{

src/GraphQL/Types/QueryArgument.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public QueryArgument(Type type)
2020

2121
public string Name { get; set; }
2222

23+
public string Description { get; set; }
24+
2325
public object DefaultValue { get; set; }
2426

2527
public Type Type { get; private set; }

0 commit comments

Comments
 (0)