Skip to content

Commit fe110b6

Browse files
committed
add StarWars schema classes, fix local execution client
1 parent ce649f7 commit fe110b6

File tree

20 files changed

+400
-13
lines changed

20 files changed

+400
-13
lines changed

src/GraphQL.Client.LocalExecution/GraphQL.Client.LocalExecution.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="GraphQL" Version="2.4.0" />
12-
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
13-
<PackageReference Include="System.Reactive.Compatibility" Version="4.3.2" />
11+
<PackageReference Include="GraphQL" Version="4.6.0" />
12+
<PackageReference Include="GraphQL.NewtonsoftJson" Version="4.6.0" />
13+
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
1414
</ItemGroup>
1515

1616
<ItemGroup>

src/GraphQL.Client.LocalExecution/GraphQLLocalExecutionClient.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Threading.Tasks;
1010
using GraphQL.Client.Abstractions;
1111
using GraphQL.Client.Serializer.Newtonsoft;
12+
using GraphQL.NewtonsoftJson;
1213
using GraphQL.Subscription;
1314
using GraphQL.Types;
1415
using Newtonsoft.Json;
@@ -41,6 +42,7 @@ public class GraphQLLocalExecutionClient<TSchema> : IGraphQLClient where TSchema
4142
public IGraphQLJsonSerializer Serializer { get; }
4243

4344
private readonly DocumentExecuter _documentExecuter;
45+
private readonly DocumentWriter _documentWriter;
4446

4547
public GraphQLLocalExecutionClient(TSchema schema, IGraphQLJsonSerializer serializer)
4648
{
@@ -50,6 +52,7 @@ public GraphQLLocalExecutionClient(TSchema schema, IGraphQLJsonSerializer serial
5052
if (!Schema.Initialized)
5153
Schema.Initialize();
5254
_documentExecuter = new DocumentExecuter();
55+
_documentWriter = new DocumentWriter();
5356
}
5457

5558
public void Dispose() { }
@@ -109,12 +112,13 @@ private async Task<ExecutionResult> ExecuteAsync(GraphQLRequest request, Cancell
109112
return result;
110113
}
111114

112-
private Task<GraphQLResponse<TResponse>> ExecutionResultToGraphQLResponse<TResponse>(ExecutionResult executionResult, CancellationToken cancellationToken = default)
115+
private async Task<GraphQLResponse<TResponse>> ExecutionResultToGraphQLResponse<TResponse>(ExecutionResult executionResult, CancellationToken cancellationToken = default)
113116
{
117+
string json = await _documentWriter.WriteToStringAsync(executionResult);
114118
// serialize result into utf8 byte stream
115-
var resultStream = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(executionResult, _variablesSerializerSettings)));
119+
var resultStream = new MemoryStream(Encoding.UTF8.GetBytes(json));
116120
// deserialize using the provided serializer
117-
return Serializer.DeserializeFromUtf8StreamAsync<TResponse>(resultStream, cancellationToken);
121+
return await Serializer.DeserializeFromUtf8StreamAsync<TResponse>(resultStream, cancellationToken);
118122
}
119123

120124
#endregion

tests/GraphQL.Client.Serializer.Tests/BaseSerializerTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using GraphQL.Client.Tests.Common.Chat.Schema;
1717
using GraphQL.Client.Tests.Common.Helpers;
1818
using GraphQL.Client.Tests.Common.StarWars;
19+
using GraphQL.Client.Tests.Common.StarWars.TestData;
1920
using Xunit;
2021

2122
namespace GraphQL.Client.Serializer.Tests

tests/GraphQL.Client.Tests.Common/Common.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using GraphQL.Client.Tests.Common.Chat.Schema;
2-
using GraphQL.StarWars;
3-
using GraphQL.StarWars.Types;
2+
using GraphQL.Client.Tests.Common.StarWars;
3+
using GraphQL.Client.Tests.Common.StarWars.Types;
44
using Microsoft.Extensions.DependencyInjection;
55

66
namespace GraphQL.Client.Tests.Common

tests/GraphQL.Client.Tests.Common/GraphQL.Client.Tests.Common.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
<PackageReference Include="FluentAssertions" Version="5.10.3" />
1010
<PackageReference Include="GraphQL" Version="4.6.0" />
1111
<PackageReference Include="GraphQL.Server.Transports.Subscriptions.Abstractions" Version="5.0.2" />
12-
<PackageReference Include="GraphQL.StarWars" Version="1.0.0" />
1312
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
1413
<PackageReference Include="Microsoft.Reactive.Testing" Version="5.0.0" />
1514
</ItemGroup>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using GraphQL.Builders;
5+
using GraphQL.Client.Tests.Common.StarWars.Types;
6+
using GraphQL.Types.Relay.DataObjects;
7+
8+
namespace GraphQL.Client.Tests.Common.StarWars.Extensions
9+
{
10+
public static class ResolveFieldContextExtensions
11+
{
12+
public static Connection<U> GetPagedResults<T, U>(this IResolveConnectionContext<T> context, StarWarsData data, List<string> ids) where U : StarWarsCharacter
13+
{
14+
List<string> idList;
15+
List<U> list;
16+
string cursor;
17+
string endCursor;
18+
var pageSize = context.PageSize ?? 20;
19+
20+
if (context.IsUnidirectional || context.After != null || context.Before == null)
21+
{
22+
if (context.After != null)
23+
{
24+
idList = ids
25+
.SkipWhile(x => !Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(x)).Equals(context.After))
26+
.Take(context.First ?? pageSize).ToList();
27+
}
28+
else
29+
{
30+
idList = ids
31+
.Take(context.First ?? pageSize).ToList();
32+
}
33+
}
34+
else
35+
{
36+
if (context.Before != null)
37+
{
38+
idList = ids.Reverse<string>()
39+
.SkipWhile(x => !Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(x)).Equals(context.Before))
40+
.Take(context.Last ?? pageSize).ToList();
41+
}
42+
else
43+
{
44+
idList = ids.Reverse<string>()
45+
.Take(context.Last ?? pageSize).ToList();
46+
}
47+
}
48+
49+
list = data.GetCharactersAsync(idList).Result as List<U> ?? throw new InvalidOperationException($"GetCharactersAsync method should return list of '{typeof(U).Name}' items.");
50+
cursor = list.Count > 0 ? list.Last().Cursor : null;
51+
endCursor = ids.Count > 0 ? Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(ids.Last())) : null;
52+
53+
return new Connection<U>
54+
{
55+
Edges = list.Select(x => new Edge<U> { Cursor = x.Cursor, Node = x }).ToList(),
56+
TotalCount = list.Count,
57+
PageInfo = new PageInfo
58+
{
59+
EndCursor = endCursor,
60+
HasNextPage = endCursor == null ? false : cursor != endCursor,
61+
}
62+
};
63+
}
64+
}
65+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using GraphQL.Client.Tests.Common.StarWars.Types;
5+
6+
namespace GraphQL.Client.Tests.Common.StarWars
7+
{
8+
public class StarWarsData
9+
{
10+
private readonly List<StarWarsCharacter> _characters = new List<StarWarsCharacter>();
11+
12+
public StarWarsData()
13+
{
14+
_characters.Add(new Human
15+
{
16+
Id = "1",
17+
Name = "Luke",
18+
Friends = new List<string> { "3", "4" },
19+
AppearsIn = new[] { 4, 5, 6 },
20+
HomePlanet = "Tatooine",
21+
Cursor = "MQ=="
22+
});
23+
_characters.Add(new Human
24+
{
25+
Id = "2",
26+
Name = "Vader",
27+
AppearsIn = new[] { 4, 5, 6 },
28+
HomePlanet = "Tatooine",
29+
Cursor = "Mg=="
30+
});
31+
32+
_characters.Add(new Droid
33+
{
34+
Id = "3",
35+
Name = "R2-D2",
36+
Friends = new List<string> { "1", "4" },
37+
AppearsIn = new[] { 4, 5, 6 },
38+
PrimaryFunction = "Astromech",
39+
Cursor = "Mw=="
40+
});
41+
_characters.Add(new Droid
42+
{
43+
Id = "4",
44+
Name = "C-3PO",
45+
AppearsIn = new[] { 4, 5, 6 },
46+
PrimaryFunction = "Protocol",
47+
Cursor = "NA=="
48+
});
49+
}
50+
51+
public IEnumerable<StarWarsCharacter> GetFriends(StarWarsCharacter character)
52+
{
53+
if (character == null)
54+
{
55+
return null;
56+
}
57+
58+
var friends = new List<StarWarsCharacter>();
59+
var lookup = character.Friends;
60+
if (lookup != null)
61+
{
62+
foreach (var c in _characters.Where(h => lookup.Contains(h.Id)))
63+
friends.Add(c);
64+
}
65+
return friends;
66+
}
67+
68+
public StarWarsCharacter AddCharacter(StarWarsCharacter character)
69+
{
70+
character.Id = _characters.Count.ToString();
71+
_characters.Add(character);
72+
return character;
73+
}
74+
75+
public Task<Human> GetHumanByIdAsync(string id)
76+
{
77+
return Task.FromResult(_characters.FirstOrDefault(h => h.Id == id && h is Human) as Human);
78+
}
79+
80+
public Task<Droid> GetDroidByIdAsync(string id)
81+
{
82+
return Task.FromResult(_characters.FirstOrDefault(h => h.Id == id && h is Droid) as Droid);
83+
}
84+
85+
public Task<List<StarWarsCharacter>> GetCharactersAsync(List<string> guids)
86+
{
87+
return Task.FromResult(_characters.Where(c => guids.Contains(c.Id)).ToList());
88+
}
89+
}
90+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using GraphQL.Client.Tests.Common.StarWars.Types;
2+
using GraphQL.Types;
3+
4+
namespace GraphQL.Client.Tests.Common.StarWars
5+
{
6+
/// <example>
7+
/// This is an example JSON request for a mutation
8+
/// {
9+
/// "query": "mutation ($human:HumanInput!){ createHuman(human: $human) { id name } }",
10+
/// "variables": {
11+
/// "human": {
12+
/// "name": "Boba Fett"
13+
/// }
14+
/// }
15+
/// }
16+
/// </example>
17+
public class StarWarsMutation : ObjectGraphType<object>
18+
{
19+
public StarWarsMutation(StarWarsData data)
20+
{
21+
Name = "Mutation";
22+
23+
Field<HumanType>(
24+
"createHuman",
25+
arguments: new QueryArguments(
26+
new QueryArgument<NonNullGraphType<HumanInputType>> { Name = "human" }
27+
),
28+
resolve: context =>
29+
{
30+
var human = context.GetArgument<Human>("human");
31+
return data.AddCharacter(human);
32+
});
33+
}
34+
}
35+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using GraphQL.Client.Tests.Common.StarWars.Types;
3+
using GraphQL.Types;
4+
5+
namespace GraphQL.Client.Tests.Common.StarWars
6+
{
7+
public class StarWarsQuery : ObjectGraphType<object>
8+
{
9+
public StarWarsQuery(StarWarsData data)
10+
{
11+
Name = "Query";
12+
13+
Field<CharacterInterface>("hero", resolve: context => data.GetDroidByIdAsync("3"));
14+
Field<HumanType>(
15+
"human",
16+
arguments: new QueryArguments(
17+
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "id", Description = "id of the human" }
18+
),
19+
resolve: context => data.GetHumanByIdAsync(context.GetArgument<string>("id"))
20+
);
21+
22+
Func<IResolveFieldContext, string, object> func = (context, id) => data.GetDroidByIdAsync(id);
23+
24+
FieldDelegate<DroidType>(
25+
"droid",
26+
arguments: new QueryArguments(
27+
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "id", Description = "id of the droid" }
28+
),
29+
resolve: func
30+
);
31+
}
32+
}
33+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using GraphQL.Types;
3+
using Microsoft.Extensions.DependencyInjection;
4+
5+
namespace GraphQL.Client.Tests.Common.StarWars
6+
{
7+
public class StarWarsSchema : Schema
8+
{
9+
public StarWarsSchema(IServiceProvider serviceProvider)
10+
: base(serviceProvider)
11+
{
12+
Query = serviceProvider.GetRequiredService<StarWarsQuery>();
13+
Mutation = serviceProvider.GetRequiredService<StarWarsMutation>();
14+
15+
Description = "Example StarWars universe schema";
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)