Support query batching
This commit is contained in:
parent
9e29d5f22d
commit
9909493bfc
3 changed files with 99 additions and 81 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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
101
composer.lock
generated
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue