new Deps
This commit is contained in:
@@ -2,29 +2,32 @@
|
||||
|
||||
namespace Nuwave\Lighthouse\Execution\DataLoader;
|
||||
|
||||
use Exception;
|
||||
use GraphQL\Deferred;
|
||||
use Illuminate\Support\Collection;
|
||||
use Nuwave\Lighthouse\Execution\GraphQLRequest;
|
||||
use Nuwave\Lighthouse\Support\Traits\HandlesCompositeKey;
|
||||
|
||||
/**
|
||||
* @deprecated implement your own batch loader instead.
|
||||
* @see \Nuwave\Lighthouse\Execution\BatchLoader\BatchLoaderRegistry to resolve instances.
|
||||
*/
|
||||
abstract class BatchLoader
|
||||
{
|
||||
use HandlesCompositeKey;
|
||||
/**
|
||||
* Active BatchLoader instances.
|
||||
*
|
||||
* @var array<string, static>
|
||||
*/
|
||||
protected static $instances = [];
|
||||
|
||||
/**
|
||||
* Keys to resolve.
|
||||
* Map from keys to metainfo for resolving.
|
||||
*
|
||||
* @var array
|
||||
* @var array<mixed, array<mixed>>
|
||||
*/
|
||||
protected $keys = [];
|
||||
|
||||
/**
|
||||
* Map of loaded results.
|
||||
* Map from keys to resolved values.
|
||||
*
|
||||
* [key => resolvedValue]
|
||||
*
|
||||
* @var mixed[]
|
||||
* @var array<mixed, mixed>
|
||||
*/
|
||||
protected $results = [];
|
||||
|
||||
@@ -39,8 +42,8 @@ abstract class BatchLoader
|
||||
* Return an instance of a BatchLoader for a specific field.
|
||||
*
|
||||
* @param string $loaderClass The class name of the concrete BatchLoader to instantiate
|
||||
* @param mixed[] $pathToField Path to the GraphQL field from the root, is used as a key for BatchLoader instances
|
||||
* @param mixed[] $constructorArgs Those arguments are passed to the constructor of the new BatchLoader instance
|
||||
* @param array<int|string> $pathToField Path to the GraphQL field from the root, is used as a key for BatchLoader instances
|
||||
* @param array<mixed> $constructorArgs Those arguments are passed to the constructor of the new BatchLoader instance
|
||||
* @return static
|
||||
*
|
||||
* @throws \Exception
|
||||
@@ -50,60 +53,52 @@ abstract class BatchLoader
|
||||
// The path to the field serves as the unique key for the instance
|
||||
$instanceName = static::instanceKey($pathToField);
|
||||
|
||||
// If we are resolving a batched query, we need to assign each
|
||||
// query a uniquely indexed instance
|
||||
/** @var \Nuwave\Lighthouse\Execution\GraphQLRequest $graphQLRequest */
|
||||
$graphQLRequest = app(GraphQLRequest::class);
|
||||
if ($graphQLRequest->isBatched()) {
|
||||
$currentBatchIndex = $graphQLRequest->batchIndex();
|
||||
$instanceName = "batch_{$currentBatchIndex}_{$instanceName}";
|
||||
if (isset(self::$instances[$instanceName])) {
|
||||
return self::$instances[$instanceName];
|
||||
}
|
||||
|
||||
// Only register a new instance if it is not already bound
|
||||
$instance = app()->bound($instanceName)
|
||||
? app($instanceName)
|
||||
: app()->instance(
|
||||
$instanceName,
|
||||
app()->makeWith($loaderClass, $constructorArgs)
|
||||
);
|
||||
|
||||
if (! $instance instanceof self) {
|
||||
throw new Exception(
|
||||
"The given class '$loaderClass' must resolve to an instance of Nuwave\Lighthouse\Execution\DataLoader\BatchLoader"
|
||||
);
|
||||
}
|
||||
|
||||
return $instance;
|
||||
return self::$instances[$instanceName] = app()->makeWith($loaderClass, $constructorArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique key for the instance, using the path in the query.
|
||||
*
|
||||
* @param mixed[] $path
|
||||
* @return string
|
||||
* @param array<int|string> $path
|
||||
*/
|
||||
public static function instanceKey(array $path): string
|
||||
{
|
||||
return (new Collection($path))
|
||||
->filter(function ($path): bool {
|
||||
// Ignore numeric path entries, as those signify an array of fields.
|
||||
$significantPathSegments = array_filter(
|
||||
$path,
|
||||
function ($path): bool {
|
||||
// Ignore numeric path entries, as those signify a list of fields.
|
||||
// Combining the queries for those is the very purpose of the
|
||||
// batch loader, so they must not be included.
|
||||
return ! is_numeric($path);
|
||||
})
|
||||
->implode('_');
|
||||
}
|
||||
);
|
||||
$pathIgnoringLists = implode('.', $significantPathSegments);
|
||||
|
||||
return 'nuwave/lighthouse/batchloader/'.$pathIgnoringLists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load object by key.
|
||||
* Remove all stored BatchLoaders.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed[] $metaInfo
|
||||
* @return \GraphQL\Deferred
|
||||
* This is called after Lighthouse has resolved a query, so multiple
|
||||
* queries can be handled in a single request/session.
|
||||
*/
|
||||
public function load($key, array $metaInfo = []): Deferred
|
||||
public static function forgetInstances(): void
|
||||
{
|
||||
self::$instances = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a result to be loaded.
|
||||
*
|
||||
* @param array<mixed> $metaInfo
|
||||
*/
|
||||
public function load(string $key, array $metaInfo = []): Deferred
|
||||
{
|
||||
$key = $this->buildKey($key);
|
||||
$this->keys[$key] = $metaInfo;
|
||||
|
||||
return new Deferred(function () use ($key) {
|
||||
@@ -116,12 +111,29 @@ abstract class BatchLoader
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule multiple results to be loaded.
|
||||
*
|
||||
* @param array<mixed> $keys
|
||||
* @param array<mixed> $metaInfo
|
||||
* @return array<\GraphQL\Deferred>
|
||||
*/
|
||||
public function loadMany(array $keys, array $metaInfo = []): array
|
||||
{
|
||||
return array_map(
|
||||
function ($key) use ($metaInfo): Deferred {
|
||||
return $this->load($key, $metaInfo);
|
||||
},
|
||||
$keys
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the keys.
|
||||
*
|
||||
* The result has to be an associative array: [key => result]
|
||||
* The result has to be a map from keys to resolved values.
|
||||
*
|
||||
* @return mixed[]
|
||||
* @return array<mixed, mixed>
|
||||
*/
|
||||
abstract public function resolve(): array;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user