WIP update get defer to route
This commit is contained in:
parent
b4ff4aa123
commit
5010317d8b
1 changed files with 117 additions and 83 deletions
|
@ -15,7 +15,7 @@ use Utopia\App;
|
|||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\Validator;
|
||||
|
||||
|
@ -99,9 +99,9 @@ class Builder
|
|||
$fields[$escapedKey] = [
|
||||
'type' => $type,
|
||||
'description' => $props['description'],
|
||||
'resolve' => function ($object, $args, $context, $info) use ($key) {
|
||||
return $object[$key];
|
||||
}
|
||||
'resolve' => fn ($object, $args, $context, $info) => $object->then(function ($obj) use ($object, $key) {
|
||||
return $obj['result'][$key];
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -117,9 +117,9 @@ class Builder
|
|||
/**
|
||||
* Map a Utopia\Validator to a valid GraphQL Type
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param bool $required
|
||||
* @param App $utopia
|
||||
* @param Validator|callable $validator
|
||||
* @param bool $required
|
||||
* @param array $injections
|
||||
* @return Type
|
||||
* @throws \Exception
|
||||
|
@ -224,18 +224,22 @@ class Builder
|
|||
* projects collections to the base API GraphQL schema.
|
||||
*
|
||||
* @param array $apiSchema
|
||||
* @param Registry $register
|
||||
* @param App $utopia
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @param Database $dbForProject
|
||||
* @return Schema
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function appendProjectSchema(
|
||||
array $apiSchema,
|
||||
Registry $register,
|
||||
App $utopia,
|
||||
Request $request,
|
||||
Response $response,
|
||||
Database $dbForProject
|
||||
): Schema
|
||||
{
|
||||
$db = self::buildCollectionsSchema($register, $dbForProject);
|
||||
$db = self::buildCollectionsSchema($utopia, $request, $response, $dbForProject);
|
||||
|
||||
$queryFields = \array_merge_recursive($apiSchema['query'], $db['query']);
|
||||
$mutationFields = \array_merge_recursive($apiSchema['mutation'], $db['mutation']);
|
||||
|
@ -259,31 +263,34 @@ class Builder
|
|||
* This function iterates all a projects attributes and builds
|
||||
* GraphQL queries and mutations for the collections they make up.
|
||||
*
|
||||
* @param Registry $register
|
||||
* @param App $utopia
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @param Database $dbForProject
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function buildCollectionsSchema(
|
||||
Registry $register,
|
||||
App $utopia,
|
||||
Request $request,
|
||||
Response $response,
|
||||
Database $dbForProject
|
||||
): array
|
||||
{
|
||||
Console::info("[INFO] Building GraphQL Project Collection Schema...");
|
||||
$start = microtime(true);
|
||||
|
||||
$collections = [];
|
||||
$queryFields = [];
|
||||
$mutationFields = [];
|
||||
$limit = 50;
|
||||
$limit = 1000 * swoole_cpu_num();
|
||||
$offset = 0;
|
||||
|
||||
while (!empty($attrs = $dbForProject->find(
|
||||
while (!empty($attrs = Authorization::skip(fn() => $dbForProject->find(
|
||||
'attributes',
|
||||
[new Query('signed', Query::TYPE_EQUAL, [true]),],
|
||||
limit: $limit,
|
||||
offset: $offset
|
||||
))) {
|
||||
)))) {
|
||||
//go(function() use ($utopia, $request, $response, $dbForProject, &$collections, &$queryFields, &$mutationFields, $limit, &$offset, $attrs) {
|
||||
foreach ($attrs as $attr) {
|
||||
$collectionId = $attr->getAttribute('collectionId');
|
||||
if ($attr->getAttribute('status') !== 'available') {
|
||||
|
@ -296,9 +303,9 @@ class Builder
|
|||
$escapedKey = str_replace('$', '_', $key);
|
||||
$collections[$collectionId][$escapedKey] = [
|
||||
'type' => self::getAttributeArgType($type, $array, $required),
|
||||
'resolve' => function ($object, $args, $context, $info) use ($key) {
|
||||
return $object->getAttribute($key);
|
||||
}
|
||||
'resolve' => fn ($object, $args, $context, $info) => $object->then(function ($obj) use ($key) {
|
||||
return $obj['result'][$key];
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -347,10 +354,11 @@ class Builder
|
|||
return $object->getAttribute('$write');
|
||||
}
|
||||
];
|
||||
|
||||
$queryFields[$collectionId . 'Get'] = [
|
||||
'type' => $objectType,
|
||||
'args' => $idArgs,
|
||||
'resolve' => self::queryGet($collectionId, $dbForProject)
|
||||
'resolve' => self::queryGet($utopia, $request, $response, $dbForProject, $collectionId)
|
||||
];
|
||||
$queryFields[$collectionId . 'List'] = [
|
||||
'type' => $objectType,
|
||||
|
@ -373,12 +381,13 @@ class Builder
|
|||
'resolve' => self::mutateDelete($collectionId, $dbForProject)
|
||||
];
|
||||
}
|
||||
//});
|
||||
|
||||
$offset += $limit;
|
||||
}
|
||||
|
||||
$time_elapsed_secs = (microtime(true) - $start) * 1000;
|
||||
Console::info("Built GraphQL Project Collection Schema in ${time_elapsed_secs}ms");
|
||||
Console::info("[INFO] Built GraphQL Project Collection Schema in ${time_elapsed_secs}ms");
|
||||
|
||||
return [
|
||||
'query' => $queryFields,
|
||||
|
@ -386,12 +395,34 @@ class Builder
|
|||
];
|
||||
}
|
||||
|
||||
private static function queryGet(string $collectionId, Database $dbForProject): callable
|
||||
private static function queryGet(
|
||||
App $utopia,
|
||||
Request $request,
|
||||
Response $response,
|
||||
Database $dbForProject,
|
||||
string $collectionId
|
||||
): callable
|
||||
{
|
||||
return fn($type, $args, $context, $info) => new CoroutinePromise(
|
||||
function (callable $resolve, callable $reject) use ($collectionId, $type, $args, $dbForProject) {
|
||||
function (callable $resolve, callable $reject) use ($utopia, $request, $response, $dbForProject, $collectionId, $type, $args) {
|
||||
try {
|
||||
$resolve($dbForProject->getDocument($collectionId, $args['id']));
|
||||
$swooleRq = $request->getSwoole();
|
||||
$swooleRq->post = [
|
||||
'collectionId' => $collectionId,
|
||||
'documentId' => $args['id'],
|
||||
];
|
||||
// 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']);
|
||||
}
|
||||
$request = new Request($swooleRq);
|
||||
$url = '/v1/database/collections/:collectionId/documents/:documentId';
|
||||
$route = $utopia->getRoutes()['GET'][$url];
|
||||
$utopia
|
||||
->setRoute($route)
|
||||
->execute($route, $request);
|
||||
$resolve($response->getPayload());
|
||||
} catch (\Throwable $e) {
|
||||
$reject($e);
|
||||
}
|
||||
|
@ -404,7 +435,8 @@ class Builder
|
|||
return fn($type, $args, $context, $info) => new CoroutinePromise(
|
||||
function (callable $resolve, callable $reject) use ($collectionId, $type, $args, $dbForProject) {
|
||||
try {
|
||||
$resolve($dbForProject->getCollection($collectionId));
|
||||
$list = $dbForProject->find($collectionId);
|
||||
$resolve($list);
|
||||
} catch (\Throwable $e) {
|
||||
$reject($e);
|
||||
}
|
||||
|
@ -464,7 +496,6 @@ class Builder
|
|||
*/
|
||||
public static function buildAPISchema(App $utopia, Request $request, Response $response, Registry $register): array
|
||||
{
|
||||
Console::info("[INFO] Building GraphQL REST API Schema...");
|
||||
$start = microtime(true);
|
||||
|
||||
self::init();
|
||||
|
@ -480,7 +511,10 @@ class Builder
|
|||
$methodName = $namespace . \ucfirst($route->getLabel('sdk.method', ''));
|
||||
$responseModelNames = $route->getLabel('sdk.response.model', "none");
|
||||
|
||||
if ($responseModelNames !== "none") {
|
||||
if ($responseModelNames === "none") {
|
||||
continue;
|
||||
}
|
||||
|
||||
$responseModels = \is_array($responseModelNames)
|
||||
? \array_map(static fn($m) => $response->getModel($m), $responseModelNames)
|
||||
: [$response->getModel($responseModelNames)];
|
||||
|
@ -505,10 +539,11 @@ class Builder
|
|||
}
|
||||
|
||||
$resolve = fn($type, $args, $context, $info) => new CoroutinePromise(
|
||||
function (callable $resolve, callable $reject) use ($utopia, $request, $response, &$register, $route, $args) {
|
||||
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;
|
||||
|
||||
// Drop json content type so post args are used directly
|
||||
if (\array_key_exists('content-type', $swooleRq->header)
|
||||
&& $swooleRq->header['content-type'] === 'application/json') {
|
||||
|
@ -527,7 +562,8 @@ class Builder
|
|||
} else if ($response->getCurrentModel() == Response::MODEL_ERROR) {
|
||||
$reject(new GQLException($result['message'], $result['code']));
|
||||
}
|
||||
$resolve($result);
|
||||
|
||||
$resolve($result['result']);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -546,8 +582,6 @@ class Builder
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$time_elapsed_secs = (microtime(true) - $start) * 1000;
|
||||
Console::info("[INFO] Built GraphQL REST API Schema in ${time_elapsed_secs}ms");
|
||||
|
||||
|
|
Loading…
Reference in a new issue