Skip to content

Commit 2a75e5a

Browse files
committed
Refactor GraphQLClient and related classes to use a generic GraphQLRequest type for improved flexibility and clarity
1 parent 2319bd3 commit 2a75e5a

File tree

9 files changed

+40
-25
lines changed

9 files changed

+40
-25
lines changed

GraphQLSharp.Tests/GraphQLClientTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace GraphQLSharp.Tests;
77
[TestClass]
88
public class GraphQLClientTests
99
{
10-
private GraphQLClient<QueryRoot, Mutation, GraphQLClientOptions> _client;
10+
private GraphQLClient<GraphQLRequest, GraphQLClientOptions, QueryRoot, Mutation> _client;
1111

1212
[TestInitialize]
1313
public void Initialize()

GraphQLSharp.Tests/shopify.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace Shopify
1212
{
13-
public partial class GraphQLClient : GraphQLClient<Shopify.Types.QueryRoot, Shopify.Types.Mutation, GraphQLClientOptions>
13+
public partial class GraphQLClient : GraphQLClient<GraphQLRequest, GraphQLClientOptions, Shopify.Types.QueryRoot, Shopify.Types.Mutation>
1414
{
1515
public GraphQLClient(GraphQLClientOptions? defaultOptions = null) : base(defaultOptions!)
1616
{

GraphQLSharp.Tests/square.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace Square
1212
{
13-
public partial class GraphQLClient : GraphQLClient<Square.Types.Query, GraphQLClientOptions>
13+
public partial class GraphQLClient : GraphQLClient<GraphQLRequest, GraphQLClientOptions, Square.Types.Query>
1414
{
1515
public GraphQLClient(GraphQLClientOptions? defaultOptions = null) : base(defaultOptions!)
1616
{

GraphQLSharp/Client/GraphQLClient.cs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
namespace GraphQLSharp;
77

8-
public class GraphQLClient<TQueryRoot, TMutationRoot, TClientOptions> : GraphQLClient<TQueryRoot, TClientOptions>
8+
public class GraphQLClient<TGraphQLRequest, TClientOptions, TQueryRoot, TMutationRoot> : GraphQLClient<TGraphQLRequest, TClientOptions, TQueryRoot>
9+
where TGraphQLRequest : GraphQLRequest, new()
910
where TQueryRoot : class
1011
where TMutationRoot : class
1112
where TClientOptions : GraphQLClientOptions
@@ -19,13 +20,14 @@ public Task<GraphQLResponse<TMutationRoot>> ExecuteMutationAsync([StringSyntax("
1920
return ExecuteAsync<TMutationRoot>(query, options, cancellationToken);
2021
}
2122

22-
public Task<GraphQLResponse<TMutationRoot>> ExecuteMutationAsync(GraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
23+
public Task<GraphQLResponse<TMutationRoot>> ExecuteMutationAsync(TGraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
2324
{
2425
return ExecuteAsync<TMutationRoot>(request, options, cancellationToken);
2526
}
2627
}
2728

28-
public class GraphQLClient<TQueryRoot, TClientOptions> : GraphQLClient<TClientOptions>
29+
public class GraphQLClient<TGraphQLRequest, TClientOptions, TQueryRoot> : GraphQLClient<TGraphQLRequest, TClientOptions>
30+
where TGraphQLRequest : GraphQLRequest, new()
2931
where TQueryRoot : class
3032
where TClientOptions : GraphQLClientOptions
3133
{
@@ -38,25 +40,26 @@ public Task<GraphQLResponse<TQueryRoot>> ExecuteQueryAsync([StringSyntax("GraphQ
3840
return ExecuteAsync<TQueryRoot>(query, options, cancellationToken);
3941
}
4042

41-
public Task<GraphQLResponse<TQueryRoot>> ExecuteQueryAsync(GraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
43+
public Task<GraphQLResponse<TQueryRoot>> ExecuteQueryAsync(TGraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
4244
{
4345
return ExecuteAsync<TQueryRoot>(request, options, cancellationToken);
4446
}
4547
}
4648

47-
public class GraphQLCLient : GraphQLClient<GraphQLClientOptions>
49+
public class GraphQLCLient : GraphQLClient<GraphQLRequest, GraphQLClientOptions>
4850
{
4951
public GraphQLCLient(GraphQLClientOptions defaultOptions = null) : base(defaultOptions)
5052
{
5153
}
5254
}
5355

54-
public class GraphQLClient<TClientOptions>
56+
public class GraphQLClient<TGraphQLRequest, TClientOptions>
57+
where TGraphQLRequest : GraphQLRequest, new()
5558
where TClientOptions : GraphQLClientOptions
5659
{
5760
private static readonly HttpClient _defaultHttpClient = new();
5861

59-
private static readonly ProductInfoHeaderValue _defaultUserAgent = new(typeof(GraphQLClient<TClientOptions>).Assembly.GetName().Name!, typeof(GraphQLClient<TClientOptions>).Assembly.GetName().Version!.ToString());
62+
private static readonly ProductInfoHeaderValue _defaultUserAgent = new(typeof(GraphQLClient<TGraphQLRequest, TClientOptions>).Assembly.GetName().Name!, typeof(GraphQLClient<TGraphQLRequest, TClientOptions>).Assembly.GetName().Version!.ToString());
6063

6164
private readonly TClientOptions _defaultOptions;
6265

@@ -75,16 +78,16 @@ public Task<GraphQLResponse<JsonElement>> ExecuteAsync([StringSyntax("GraphQL")]
7578

7679
public Task<GraphQLResponse<T>> ExecuteAsync<T>([StringSyntax("GraphQL")] string query, TClientOptions options = null, CancellationToken cancellationToken = default)
7780
{
78-
return ExecuteAsync<T>(new GraphQLRequest { query = query }, options, cancellationToken);
81+
return ExecuteAsync<T>(new TGraphQLRequest { query = query }, options, cancellationToken);
7982
}
8083

81-
public Task<GraphQLResponse<JsonElement>> ExecuteAsync(GraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
84+
public Task<GraphQLResponse<JsonElement>> ExecuteAsync(TGraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
8285
{
8386
//returing JsonElement and not JsonDocument because JsonDocument is disposable and we don't want to force the user to dispose it
8487
return ExecuteAsync<JsonElement>(request, options, cancellationToken);
8588
}
8689

87-
public async Task<GraphQLResponse<T>> ExecuteAsync<T>(GraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
90+
public async Task<GraphQLResponse<T>> ExecuteAsync<T>(TGraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
8891
{
8992
var interceptor = options?.Interceptor ?? _defaultOptions?.Interceptor ?? DefaultInterceptor;
9093

@@ -100,7 +103,7 @@ public async Task<GraphQLResponse<T>> ExecuteAsync<T>(GraphQLRequest request, TC
100103
}
101104
}
102105

103-
private async Task<GraphQLResponse<T>> ExecuteCoreAsync<T>(GraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
106+
private async Task<GraphQLResponse<T>> ExecuteCoreAsync<T>(TGraphQLRequest request, TClientOptions options = null, CancellationToken cancellationToken = default)
104107
{
105108
HttpResponse httpResponse = null;
106109
try
@@ -151,8 +154,9 @@ protected virtual void ValidateOptions(TClientOptions defaultOptions, TClientOpt
151154
{
152155
}
153156

154-
private HttpRequestMessage CreateHttpRequest(GraphQLRequest request, TClientOptions options)
157+
private HttpRequestMessage CreateHttpRequest(TGraphQLRequest request, TClientOptions options)
155158
{
159+
_ = request.query ?? throw new ArgumentNullException(nameof(request.query));
156160
ValidateOptions(_defaultOptions, options);
157161
var uri = options?.Uri ?? _defaultOptions?.Uri ?? throw new ArgumentNullException($"{nameof(options)}.{nameof(options.Uri)}");
158162
var requestMessage = new HttpRequestMessage

GraphQLSharp/Client/GraphQLRequest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace GraphQLSharp;
66
public class GraphQLRequest
77
{
88
[StringSyntax("GraphQL")]
9-
public required string query { get; set; }
9+
public string query { get; set; }
1010

1111
public string operationName { get; set; }
1212

GraphQLSharp/Client/Interception/IInterceptor.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ namespace GraphQLSharp;
77
/// </summary>
88
public interface IInterceptor
99
{
10-
Task<GraphQLResponse<T>> InterceptRequestAsync<T, TClientOptions>(GraphQLRequest request,
11-
TClientOptions defaultOptions,
12-
TClientOptions options,
13-
CancellationToken cancellationToken,
14-
Func<GraphQLRequest, CancellationToken, Task<GraphQLResponse<T>>> executeAsync
15-
)
16-
where TClientOptions : GraphQLClientOptions;
10+
Task<GraphQLResponse<TData>> InterceptRequestAsync<TGraphQLRequest, TClientOptions, TData>(
11+
TGraphQLRequest request,
12+
TClientOptions defaultOptions,
13+
TClientOptions options,
14+
CancellationToken cancellationToken,
15+
Func<TGraphQLRequest, CancellationToken,
16+
Task<GraphQLResponse<TData>>> executeAsync)
17+
where TGraphQLRequest : GraphQLRequest, new()
18+
where TClientOptions : GraphQLClientOptions;
1719
}

GraphQLSharp/Client/Interception/NoOpInterceptor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ public class NoOpInterceptor : IInterceptor
66

77
private NoOpInterceptor() { }
88

9-
public Task<GraphQLResponse<T>> InterceptRequestAsync<T, TClientOptions>(GraphQLRequest request, TClientOptions defaultOptions, TClientOptions options, CancellationToken cancellationToken, Func<GraphQLRequest, CancellationToken, Task<GraphQLResponse<T>>> executeAsync) where TClientOptions : GraphQLClientOptions
9+
public Task<GraphQLResponse<T>> InterceptRequestAsync<TGraphQLRequest, TClientOptions, T>(TGraphQLRequest request, TClientOptions defaultOptions, TClientOptions options, CancellationToken cancellationToken, Func<TGraphQLRequest, CancellationToken, Task<GraphQLResponse<T>>> executeAsync)
10+
where TGraphQLRequest : GraphQLRequest, new()
11+
where TClientOptions : GraphQLClientOptions
1012
{
1113
return executeAsync(request, cancellationToken);
1214
}

GraphQLSharp/TypeGenerator/GraphQLTypeGenerator.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public string GenerateTypes(GraphQLTypeGeneratorOptions options, JsonDocument in
144144
var queryType = schemaElt.GetProperty("queryType").GetProperty("name").GetString();
145145
var mutationType = schemaElt.TryGetProperty("mutationType", out var elt) && elt.ValueKind == JsonValueKind.Object ? elt.GetProperty("name").GetString() : null;
146146
var clientOptionsTypeName = options.ClientOptionsType == null ? typeof(GraphQLClientOptions).Name : options.ClientOptionsType.FullName;
147+
var graphQLRequestTypeName = options.GraphQLRequestType == null ? typeof(GraphQLRequest).Name : options.GraphQLRequestType.FullName;
147148

148149
var context = new Context();
149150
var str = context.StrBuilder;
@@ -158,7 +159,7 @@ public string GenerateTypes(GraphQLTypeGeneratorOptions options, JsonDocument in
158159
.AppendLine($"namespace {options.NamespaceClient} {{")
159160
//generating partial class to allow for extension methods and member overrides
160161
.AppendLine("public partial class GraphQLClient : ")
161-
.AppendLine(mutationType == null ? $"GraphQLClient<{options.NamespaceTypes}.{queryType}, {clientOptionsTypeName}>" : $"GraphQLClient<{options.NamespaceTypes}.{queryType}, {options.NamespaceTypes}.{mutationType}, {clientOptionsTypeName}>")
162+
.AppendLine(mutationType == null ? $"GraphQLClient<{graphQLRequestTypeName}, {clientOptionsTypeName}, {options.NamespaceTypes}.{queryType}>" : $"GraphQLClient<{graphQLRequestTypeName}, {clientOptionsTypeName}, {options.NamespaceTypes}.{queryType}, {options.NamespaceTypes}.{mutationType}>")
162163
.AppendLine($$"""
163164
{
164165
public GraphQLClient({{clientOptionsTypeName}}? defaultOptions = null) : base(defaultOptions!)

GraphQLSharp/TypeGenerator/GraphQLTypeGeneratorOptions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ public class GraphQLTypeGeneratorOptions
3535
/// </summary>
3636
public Type ClientOptionsType { get; set; }
3737

38+
/// <summary>
39+
/// An optional Type that represents the GraphQLRequest for the generated GraphQL client.
40+
/// The type must inherit from GraphQLRequest.
41+
/// </summary>
42+
public Type GraphQLRequestType { get; set; }
43+
3844
/// <summary>
3945
/// Indicates whether to generate member names for the GraphQL types.
4046
/// Defaults to false

0 commit comments

Comments
 (0)