1
0
Fork 0
mirror of synced 2024-07-02 21:20:58 +12:00

Support query batching

This commit is contained in:
Jake Barnby 2022-07-13 15:49:59 +12:00
parent 9e29d5f22d
commit 9909493bfc
3 changed files with 99 additions and 81 deletions

View file

@ -27,9 +27,7 @@ App::get('/v1/graphql')
->label('sdk.response.model', Response::MODEL_ANY) ->label('sdk.response.model', Response::MODEL_ANY)
->label('abuse-limit', 60) ->label('abuse-limit', 60)
->label('abuse-time', 60) ->label('abuse-time', 60)
->param('query', '', new Text(2048), 'The query to execute. Max 2048 chars') ->param('query', '', new JSON(), 'The query or queries to execute.', body: true)
->param('operationName', null, new Text(512), 'Name of the operation to execute. Required if multiple operations are provided', true)
->param('variables', [], new JSON(), 'Map of variables to use as replacement values in the query', true)
->inject('request') ->inject('request')
->inject('response') ->inject('response')
->inject('utopia') ->inject('utopia')
@ -52,11 +50,7 @@ App::post('/v1/graphql')
->label('sdk.response.model', Response::MODEL_ANY) ->label('sdk.response.model', Response::MODEL_ANY)
->label('abuse-limit', 60) ->label('abuse-limit', 60)
->label('abuse-time', 60) ->label('abuse-time', 60)
->param('query', '', new Text(2048), 'The query to execute. Max 1024 chars. Required if the request content type is "application/json"', true) ->param('query', '', new JSON(), 'The query or queries to execute.', body: true)
->param('operationName', null, new Text(512), 'Name of the operation to execute. Required if multiple operations are provided', true)
->param('variables', [], new JSON(), 'Map of variables to use as replacement values in the query', true)
->param('operations', '', new Text(4096), 'JSON encoded query and variables with nulled file values. Required if the request content type "multipart/form-data"', true)
->param('map', '', new Text(1024), 'Map of form-data filenames to the operations dot-path to inject the file to. For example: "variables.file"', true)
->inject('request') ->inject('request')
->inject('response') ->inject('response')
->inject('promiseAdapter') ->inject('promiseAdapter')
@ -68,11 +62,7 @@ App::post('/v1/graphql')
* @throws \Exception * @throws \Exception
*/ */
function graphqlRequest( function graphqlRequest(
string $query, array $query,
?string $operationName,
?array $variables,
?string $operations,
?string $map,
Appwrite\Utopia\Request $request, Appwrite\Utopia\Request $request,
Appwrite\Utopia\Response $response, Appwrite\Utopia\Response $response,
CoroutinePromiseAdapter $promiseAdapter, CoroutinePromiseAdapter $promiseAdapter,
@ -81,17 +71,23 @@ function graphqlRequest(
$contentType = $request->getHeader('content-type'); $contentType = $request->getHeader('content-type');
if ($contentType === 'application/graphql') { if ($contentType === 'application/graphql') {
$query = $request->getSwoole()->rawContent(); $query = [ 'query' => $request->getSwoole()->rawContent() ];
}
$batch = true;
if (!isset($query[0])) {
$batch = false;
$query = [$query];
} }
if (\str_starts_with($contentType, 'multipart/form-data')) { if (\str_starts_with($contentType, 'multipart/form-data')) {
$operations = \json_decode($operations, true); $operations = \json_decode($query[0]['operations'], true);
$map = \json_decode($map, true); $map = \json_decode($query[0]['map'], true);
foreach ($map as $fileKey => $locations) { foreach ($map as $fileKey => $locations) {
foreach ($locations as $location) { foreach ($locations as $location) {
$items = &$operations; $items = &$operations;
foreach (explode('.', $location) as $key) { foreach (\explode('.', $location) as $key) {
if (!isset($items[$key]) || !is_array($items[$key])) { if (!isset($items[$key]) || !\is_array($items[$key])) {
$items[$key] = []; $items[$key] = [];
} }
$items = &$items[$key]; $items = &$items[$key];
@ -99,8 +95,8 @@ function graphqlRequest(
$items = $request->getFiles($fileKey); $items = $request->getFiles($fileKey);
} }
} }
$query = $operations['query']; $query[0]['query'] = $operations['query'];
$variables = $operations['variables']; $query[0]['variables'] = $operations['variables'];
} }
if (empty($query)) { if (empty($query)) {
@ -121,21 +117,31 @@ function graphqlRequest(
$debugFlags = DebugFlag::NONE; $debugFlags = DebugFlag::NONE;
} }
$promise = GraphQL::promiseToExecute( $promises = [];
foreach($query as $indexed) {
$promises[] = GraphQL::promiseToExecute(
$promiseAdapter, $promiseAdapter,
$gqlSchema, $gqlSchema,
$query, $indexed['query'],
variableValues: $variables, variableValues: $indexed['variables'],
operationName: $operationName, operationName: $indexed['operationName'],
validationRules: $validations validationRules: $validations
); );
}
$output = []; $output = [];
$wg = new WaitGroup(); $wg = new WaitGroup();
$wg->add(); $wg->add();
$promise->then( $promiseAdapter->all($promises)->then(
function ($result) use ($response, &$output, $wg, $debugFlags) { function ($result) use ($response, &$output, $wg, $debugFlags) {
$output = $result->toArray($debugFlags); foreach ($result as $queryResponse) {
$output[] = $queryResponse->toArray($debugFlags);
}
if (isset($output[1])) {
$output = \array_merge_recursive(...$output);
} else {
$output = $output[0];
}
$wg->done(); $wg->done();
}, },
function ($error) use ($response, &$output, $wg) { function ($error) use ($response, &$output, $wg) {

View file

@ -42,7 +42,7 @@
"ext-sockets": "*", "ext-sockets": "*",
"appwrite/php-clamav": "1.1.*", "appwrite/php-clamav": "1.1.*",
"appwrite/php-runtimes": "0.10.*", "appwrite/php-runtimes": "0.10.*",
"abnegate/framework": "dev-feat-graphql-helpers", "utopia-php/framework": "dev-feat-graphql-helpers as 0.19.2",
"utopia-php/logger": "0.3.*", "utopia-php/logger": "0.3.*",
"utopia-php/abuse": "0.7.*", "utopia-php/abuse": "0.7.*",
"utopia-php/analytics": "0.2.*", "utopia-php/analytics": "0.2.*",
@ -70,17 +70,10 @@
"slickdeals/statsd": "3.1.0", "slickdeals/statsd": "3.1.0",
"webonyx/graphql-php": "14.1.1" "webonyx/graphql-php": "14.1.1"
}, },
"replace": {
"utopia-php/framework": "*"
},
"repositories": [ "repositories": [
{ {
"url": "https://github.com/appwrite/runtimes.git", "url": "https://github.com/appwrite/runtimes.git",
"type": "git" "type": "git"
},
{
"url": "https://github.com/abnegate/framework.git",
"type": "git"
} }
], ],
"require-dev": { "require-dev": {

101
composer.lock generated
View file

@ -4,46 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "e47b45e70996f8046494cc0db6aeb761", "content-hash": "b395a62241bc19cb1b7d845e3287808b",
"packages": [ "packages": [
{
"name": "abnegate/framework",
"version": "dev-feat-graphql-helpers",
"source": {
"type": "git",
"url": "https://github.com/abnegate/framework.git",
"reference": "a3bf64536f2d86728a06097717a5cc351d0a88d0"
},
"require": {
"php": ">=8.0.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5.10",
"vimeo/psalm": "4.13.1"
},
"type": "library",
"autoload": {
"psr-4": {
"Utopia\\": "src/"
}
},
"license": [
"MIT"
],
"authors": [
{
"name": "Eldad Fux",
"email": "eldad@appwrite.io"
}
],
"description": "A simple, light and advanced PHP framework",
"keywords": [
"framework",
"php",
"upf"
],
"time": "2022-07-12T00:06:19+00:00"
},
{ {
"name": "adhocore/jwt", "name": "adhocore/jwt",
"version": "1.1.2", "version": "1.1.2",
@ -2205,6 +2167,56 @@
}, },
"time": "2020-02-23T07:40:02+00:00" "time": "2020-02-23T07:40:02+00:00"
}, },
{
"name": "utopia-php/framework",
"version": "dev-feat-graphql-helpers",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/framework.git",
"reference": "ab785d1605cf1a01cfb9d38f87a15235cdcdf2ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/framework/zipball/ab785d1605cf1a01cfb9d38f87a15235cdcdf2ca",
"reference": "ab785d1605cf1a01cfb9d38f87a15235cdcdf2ca",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^9.5.10",
"vimeo/psalm": "4.13.1"
},
"type": "library",
"autoload": {
"psr-4": {
"Utopia\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Eldad Fux",
"email": "eldad@appwrite.io"
}
],
"description": "A simple, light and advanced PHP framework",
"keywords": [
"framework",
"php",
"upf"
],
"support": {
"issues": "https://github.com/utopia-php/framework/issues",
"source": "https://github.com/utopia-php/framework/tree/feat-graphql-helpers"
},
"time": "2022-07-13T03:41:04+00:00"
},
{ {
"name": "utopia-php/image", "name": "utopia-php/image",
"version": "0.5.4", "version": "0.5.4",
@ -5401,10 +5413,17 @@
"time": "2022-05-17T05:48:52+00:00" "time": "2022-05-17T05:48:52+00:00"
} }
], ],
"aliases": [], "aliases": [
{
"package": "utopia-php/framework",
"version": "dev-feat-graphql-helpers",
"alias": "0.19.2",
"alias_normalized": "0.19.2.0"
}
],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": { "stability-flags": {
"abnegate/framework": 20, "utopia-php/framework": 20,
"utopia-php/registry": 20 "utopia-php/registry": 20
}, },
"prefer-stable": false, "prefer-stable": false,