core
core copied to clipboard
[GraphQL] Batch requests in Apollo format
Description
This Apollo extension allow us to send multiple request at the same time:
https://www.apollographql.com/docs/link/links/batch-http/
It will be a good feature to have since we don't support sub class mutation( because of Input union spec) and it force client to send several requests for one action.I think this plugin solve some part of performance issue.
Here is Apollo client Article:
https://blog.apollographql.com/query-batching-in-apollo-63acfd859862
This plugin changes the requests to this format:
[
{
query: < query 0 >,
variables: < variables for query 0 >,
},
{
query: < query 1 >,
variables: < variables for query 1 >,
},
{
query: < query n >
variables: < variables for query n >,
}
]
I think we have two option to implement this part:
-
Using
StandardServer
This is good but we need to rewrite request process and remove the current GraphQl executor and replace it withStandardServer
. BecauseStandardServer
don't support the file upload we need to process the requests just like before. -
Calling executor several times. This is the easiest option for implementation.
I wanted to create a pull request for this, I thought its better to talk about it first.
What do you think?
It would be nice to have this feature sure :slightly_smiling_face:
We are not using the StandardServer
to have more control of the API.
So it's definitely the second option.
Looks good to me as well 🙂
Curious if this was ever revisited?
A very rough tweak to the GraphQL entrypoint action __invoke()
method would easily parse and handle batched queries.
$requestContent = $request->query->all();
if (isset($content[0]) && is_array($content[0])) {
// GQL Response returned as array of execution responses
$executionResult = [];
// Loop through batched query
foreach ($content as $singleQuery) {
// Handle each query as a single query
[$query, $operationName, $variables] = $this->parseRequest($request);
if (null === $query) {
throw new BadRequestHttpException('GraphQL query is not valid.');
}
// should probably be in its own method so its can be called in this loop and on single queries
try {
$singleExecutionResult = $this->executor->executeQuery(...); // etc
} catch (\Exception $exception) {
$singleExecutionResult = (new ExecutionResult(...)); // etc
}
// Push new result as array to main result array
$executionResult[] = $singleExecutionResult->toArray($this->debug);
}
// Return the array of responses
return new JsonResponse($executionResult);
} else {
// same process as it is now
}
// Return the array of responses
return new JsonResponse($executionResult);
I don't think query batching is necessary or even supported in graphql playground, so this can simply resolve for only the non-html requests to the gql endpoint.
Seems like a really simple and quick implementation to utilising query batching. Sure, it doesn't save on db executions, but this does save on server overhead by cutting out many multiples of network requests that could be consolidated.