Skip to content

Commit a85774f

Browse files
authored
Fix batched results with a single request (#753)
1 parent c226f3a commit a85774f

File tree

3 files changed

+20
-10
lines changed

3 files changed

+20
-10
lines changed

src/Transports.AspNetCore/GraphQLHttpMiddleware.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public virtual async Task InvokeAsync(HttpContext context, RequestDelegate next)
6565

6666
// Parse POST body
6767
GraphQLRequest bodyGQLRequest = null;
68-
GraphQLRequest[] bodyGQLBatchRequest = null;
68+
IList<GraphQLRequest> bodyGQLBatchRequest = null;
6969
if (isPost)
7070
{
7171
if (!MediaTypeHeaderValue.TryParse(httpRequest.ContentType, out var mediaTypeHeader))
@@ -77,7 +77,7 @@ public virtual async Task InvokeAsync(HttpContext context, RequestDelegate next)
7777
switch (mediaTypeHeader.MediaType)
7878
{
7979
case MediaType.JSON:
80-
GraphQLRequest[] deserializationResult;
80+
IList<GraphQLRequest> deserializationResult;
8181
try
8282
{
8383
#if NET5_0_OR_GREATER
@@ -90,14 +90,14 @@ public virtual async Task InvokeAsync(HttpContext context, RequestDelegate next)
9090
if (sourceEncoding != null && sourceEncoding != System.Text.Encoding.UTF8)
9191
{
9292
using var tempStream = System.Text.Encoding.CreateTranscodingStream(httpRequest.Body, innerStreamEncoding: sourceEncoding, outerStreamEncoding: System.Text.Encoding.UTF8, leaveOpen: true);
93-
deserializationResult = await _serializer.ReadAsync<GraphQLRequest[]>(tempStream, cancellationToken);
93+
deserializationResult = await _serializer.ReadAsync<IList<GraphQLRequest>>(tempStream, cancellationToken);
9494
}
9595
else
9696
{
97-
deserializationResult = await _serializer.ReadAsync<GraphQLRequest[]>(httpRequest.Body, cancellationToken);
97+
deserializationResult = await _serializer.ReadAsync<IList<GraphQLRequest>>(httpRequest.Body, cancellationToken);
9898
}
9999
#else
100-
deserializationResult = await _serializer.ReadAsync<GraphQLRequest[]>(httpRequest.Body, cancellationToken);
100+
deserializationResult = await _serializer.ReadAsync<IList<GraphQLRequest>>(httpRequest.Body, cancellationToken);
101101
#endif
102102
}
103103
catch (Exception ex)
@@ -106,7 +106,8 @@ public virtual async Task InvokeAsync(HttpContext context, RequestDelegate next)
106106
throw;
107107
return;
108108
}
109-
if (deserializationResult?.Length == 1)
109+
// https://github.com/graphql-dotnet/server/issues/751
110+
if (deserializationResult is GraphQLRequest[] array && array.Length == 1)
110111
bodyGQLRequest = deserializationResult[0];
111112
else
112113
bodyGQLBatchRequest = deserializationResult;
@@ -172,7 +173,7 @@ protected virtual async Task HandleRequestAsync(
172173
HttpContext context,
173174
RequestDelegate next,
174175
IDictionary<string, object> userContext,
175-
GraphQLRequest[] bodyGQLBatchRequest,
176+
IList<GraphQLRequest> bodyGQLBatchRequest,
176177
GraphQLRequest gqlRequest,
177178
IGraphQLExecuter<TSchema> executer,
178179
CancellationToken cancellationToken)
@@ -191,8 +192,8 @@ protected virtual async Task HandleRequestAsync(
191192
// Execute multiple graphql requests in one batch
192193
else
193194
{
194-
var executionResults = new ExecutionResult[bodyGQLBatchRequest.Length];
195-
for (int i = 0; i < bodyGQLBatchRequest.Length; ++i)
195+
var executionResults = new ExecutionResult[bodyGQLBatchRequest.Count];
196+
for (int i = 0; i < bodyGQLBatchRequest.Count; ++i)
196197
{
197198
var gqlRequestInBatch = bodyGQLBatchRequest[i];
198199

tests/ApiApprovalTests/GraphQL.Server.Transports.AspNetCore.approved.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace GraphQL.Server.Transports.AspNetCore
3232
protected virtual System.Threading.Tasks.Task HandleInvalidContentTypeErrorAsync(Microsoft.AspNetCore.Http.HttpContext context) { }
3333
protected virtual System.Threading.Tasks.Task HandleInvalidHttpMethodErrorAsync(Microsoft.AspNetCore.Http.HttpContext context) { }
3434
protected virtual System.Threading.Tasks.Task HandleNoQueryErrorAsync(Microsoft.AspNetCore.Http.HttpContext context) { }
35-
protected virtual System.Threading.Tasks.Task HandleRequestAsync(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.RequestDelegate next, System.Collections.Generic.IDictionary<string, object> userContext, GraphQL.Transport.GraphQLRequest[] bodyGQLBatchRequest, GraphQL.Transport.GraphQLRequest gqlRequest, GraphQL.Server.IGraphQLExecuter<TSchema> executer, System.Threading.CancellationToken cancellationToken) { }
35+
protected virtual System.Threading.Tasks.Task HandleRequestAsync(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.RequestDelegate next, System.Collections.Generic.IDictionary<string, object> userContext, System.Collections.Generic.IList<GraphQL.Transport.GraphQLRequest> bodyGQLBatchRequest, GraphQL.Transport.GraphQLRequest gqlRequest, GraphQL.Server.IGraphQLExecuter<TSchema> executer, System.Threading.CancellationToken cancellationToken) { }
3636
public virtual System.Threading.Tasks.Task InvokeAsync(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.RequestDelegate next) { }
3737
protected virtual System.Threading.Tasks.Task RequestExecutedAsync(in GraphQL.Server.Transports.AspNetCore.GraphQLRequestExecutionResult requestExecutionResult) { }
3838
protected virtual System.Threading.Tasks.Task RequestExecutingAsync(GraphQL.Transport.GraphQLRequest request, int? indexInBatch = default) { }

tests/Samples.Server.Tests/ResponseTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ public async Task Batched_Query_Should_Return_Multiple_Results()
6464
response.ShouldBeEquivalentJson(@"[{""data"":{""__schema"":{""queryType"":{""name"":""ChatQuery""}}}},{""data"":{""__schema"":{""queryType"":{""name"":""ChatQuery""}}}},{""data"":{""__schema"":{""queryType"":{""name"":""ChatQuery""}}}}]", ignoreExtensions: true);
6565
}
6666

67+
[Fact]
68+
public async Task Batched_Query_Should_Return_Single_Result_As_Array()
69+
{
70+
string response = await SendBatchRequestAsync(
71+
new GraphQLRequest { Query = "query one { __schema { queryType { name } } }", OperationName = "one" }
72+
);
73+
response.ShouldBeEquivalentJson(@"[{""data"":{""__schema"":{""queryType"":{""name"":""ChatQuery""}}}}]", ignoreExtensions: true);
74+
}
75+
6776
[Theory]
6877
[MemberData(nameof(WrongQueryData))]
6978
public async Task Wrong_Query_Should_Return_Error(HttpMethod httpMethod, HttpContent httpContent,

0 commit comments

Comments
 (0)