From 601576a9e3d7e0329029a9c00abcf7f626396653 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 20 Apr 2022 22:30:48 +1200 Subject: [PATCH] WIP fix individual param resolution --- app/controllers/api/graphql.php | 36 +++++++++++++++++--------------- src/Appwrite/GraphQL/Builder.php | 29 ++++++++++++------------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/app/controllers/api/graphql.php b/app/controllers/api/graphql.php index ef7543b44..0e7127a81 100644 --- a/app/controllers/api/graphql.php +++ b/app/controllers/api/graphql.php @@ -5,6 +5,7 @@ use Appwrite\Utopia\Response; use GraphQL\Error\DebugFlag; use GraphQL\GraphQL; use GraphQL\Type; +use GraphQL\Validator\Rules\DisableIntrospection; use GraphQL\Validator\Rules\QueryComplexity; use GraphQL\Validator\Rules\QueryDepth; use Swoole\Coroutine\WaitGroup; @@ -83,9 +84,8 @@ function graphqlRequest( /** @var Utopia\Registry\Registry $register */ /** @var \Utopia\Database\Database $dbForProject */ - // Should allow accepting entire body as query if content-type is application/graphql: - // https://graphql.org/learn/serving-over-http/#post-request if ($request->getHeader('content-type') === 'application/graphql') { + // TODO: Add getRawContent() method to Request $query = $request->getSwoole()->rawContent(); } if (empty($query)) { @@ -101,10 +101,13 @@ function graphqlRequest( [ new QueryComplexity(App::getEnv('_APP_GRAPHQL_MAX_QUERY_COMPLEXITY', 200)), new QueryDepth(App::getEnv('_APP_GRAPHQL_MAX_QUERY_DEPTH', 3)), - //new DisableIntrospection(), ] ); + if (App::isProduction()) { + $validations[] = new DisableIntrospection(); + } + $schema = Builder::appendProjectSchema( $apiSchema, $utopia, @@ -125,21 +128,20 @@ function graphqlRequest( // Blocking wait while queries resolve asynchronously $wg = new WaitGroup(); $wg->add(); - $promise->then( - function ($result) use ($response, $debugFlags, $wg) { - $result = $result->toArray($debugFlags); - if (isset($result['errors'])) { - $response->json(['data' => [], ...$result]); - $wg->done(); - return; - } - $response->json(['data' => $result]); - $wg->done(); - }, - function ($error) use ($response, $wg) { - $response->text(\json_encode(['errors' => [\json_encode($error)]])); + $promise->then(function ($result) use ($response, $debugFlags, $wg) { + $result = $result->toArray($debugFlags); + \var_dump("Result:" . $result); + if (isset($result['errors'])) { + $response->json(['data' => [], ...$result]); $wg->done(); + return; } - ); + $response->json(['data' => $result]); + $wg->done(); + }, + function ($error) use ($response, $wg) { + $response->text(\json_encode(['errors' => [\json_encode($error)]])); + $wg->done(); + }); $wg->wait(); } diff --git a/src/Appwrite/GraphQL/Builder.php b/src/Appwrite/GraphQL/Builder.php index 9b58241d5..2f9837218 100644 --- a/src/Appwrite/GraphQL/Builder.php +++ b/src/Appwrite/GraphQL/Builder.php @@ -17,6 +17,7 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; use Utopia\Registry\Registry; +use Utopia\Route; use Utopia\Validator; class Builder @@ -30,7 +31,7 @@ class Builder * * @return void */ - public static function init() + public static function init(): void { self::$typeMapping = [ Model::TYPE_BOOLEAN => Type::boolean(), @@ -99,8 +100,8 @@ class Builder $fields[$escapedKey] = [ 'type' => $type, 'description' => $props['description'], - 'resolve' => fn ($object, $args, $context, $info) => $object->then(function ($obj) use ($object, $key) { - return $obj['result'][$key]; + 'resolve' => fn ($object, $args, $context, $info) => $object->then(function ($obj) use ($object, $key, $props) { + return $obj[$key]; }), ]; } @@ -504,6 +505,8 @@ class Builder foreach ($utopia->getRoutes() as $method => $routes) { foreach ($routes as $route) { + /** @var Route $route */ + if (str_starts_with($route->getPath(), '/v1/mock/')) { continue; } @@ -541,20 +544,18 @@ class Builder $resolve = fn($type, $args, $context, $info) => new CoroutinePromise( function (callable $resolve, callable $reject) use ($utopia, $request, $response, &$register, $route, $args, $context, $info) { // Mutate the original request object to include the query variables at the top level - $swooleRq = $request->getSwoole(); - $swooleRq->post = $args; + $swoole = $request->getSwoole(); + $swoole->post = $args; // Drop json content type so post args are used directly - if (\array_key_exists('content-type', $swooleRq->header) - && $swooleRq->header['content-type'] === 'application/json') { - unset($swooleRq->header['content-type']); + if (\array_key_exists('content-type', $swoole->header) + && $swoole->header['content-type'] === 'application/json') { + unset($swoole->header['content-type']); } - $request = new Request($swooleRq); - - $utopia - ->setRoute($route) - ->execute($route, $request); + $request = new Request($swoole); + $route->getAction(); + $utopia->execute($route, $request); $result = $response->getPayload(); if ($response->getCurrentModel() == Response::MODEL_ERROR_DEV) { @@ -563,7 +564,7 @@ class Builder $reject(new GQLException($result['message'], $result['code'])); } - $resolve($result['result']); + $resolve($result); } );