Created
May 14, 2019 06:56
-
-
Save marvinrabe/85f9ac19a052137fbcf7ee446b77878a to your computer and use it in GitHub Desktop.
Nuwave Lighthouse Resolve function changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\GraphQL; | |
use GraphQL\Type\Definition\ResolveInfo; | |
use Illuminate\Support\Facades\Validator; | |
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; | |
class Request | |
{ | |
protected $rootValue; | |
protected $arguments; | |
protected $context; | |
protected $resolveInfo; | |
/** | |
* @param mixed $rootValue Usually contains the result returned from the parent field. | |
* @param mixed[] $args The arguments that were passed into the field. | |
* @param GraphQLContext $context Arbitrary data that is shared between all fields of a single query. | |
* @param ResolveInfo $resolveInfo Information about the query itself, such as the execution state, the field name, path to the field from the root, and more. | |
*/ | |
public function __construct($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) | |
{ | |
$this->rootValue = $rootValue; | |
$this->arguments = $args; | |
$this->context = $context; | |
$this->resolveInfo = $resolveInfo; | |
} | |
/** | |
* Usually contains the result returned from the parent field. | |
* @return mixed | |
*/ | |
public function rootValue() | |
{ | |
return $this->rootValue; | |
} | |
/** | |
* Information about the query itself, such as the execution state, the field name, path to the field from the root, and more. | |
* @return ResolveInfo | |
*/ | |
public function resolveInfo() | |
{ | |
return $this->resolveInfo; | |
} | |
/** | |
* Arbitrary data that is shared between all fields of a single query. | |
* @return GraphQLContext | |
*/ | |
public function context() | |
{ | |
return $this->context; | |
} | |
/** | |
* Return array of parameters to be used in dependency resolving. | |
* @return array | |
*/ | |
public function arguments() | |
{ | |
return $this->arguments; | |
} | |
/** | |
* Get the key / value list of parameters without null values. | |
* @return array | |
*/ | |
public function argumentsWithoutNulls() | |
{ | |
return array_filter($this->arguments(), function ($p) { | |
return !is_null($p); | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\GraphQL; | |
use GraphQL\Type\Definition\ResolveInfo; | |
use Illuminate\Container\Container; | |
use Illuminate\Contracts\Routing\UrlRoutable; | |
use Illuminate\Database\Eloquent\ModelNotFoundException; | |
use Illuminate\Support\Str; | |
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; | |
use ReflectionMethod; | |
use ReflectionParameter; | |
use RuntimeException; | |
abstract class Resolver | |
{ | |
/** | |
* The container instance. | |
* @var Container | |
*/ | |
protected $container; | |
/** | |
* Create a new resolver instance. | |
* @param Container $container | |
* @return void | |
*/ | |
public function __construct(Container $container) | |
{ | |
$this->container = $container; | |
} | |
public function resolve($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) | |
{ | |
$request = new Request($rootValue, $args, $context, $resolveInfo); | |
$parameters = $this->resolveDependencies($request); | |
return $this->respond(...array_values($parameters)); | |
} | |
protected function resolveDependencies(Request $request) | |
{ | |
$reflection = new ReflectionMethod($this, 'respond'); | |
$result = []; | |
foreach ($reflection->getParameters() as $key => $parameter) { | |
$result[$key] = $this->resolveDependency($request, $parameter); | |
} | |
return $result; | |
} | |
protected function resolveDependency(Request $request, ReflectionParameter $parameter) | |
{ | |
$parameters = $request->argumentsWithoutNulls(); | |
if ($parameter->getClass()) { | |
if ($parameter->getClass()->name == Request::class) { | |
return $request; | |
} | |
$instance = $this->container->make($parameter->getClass()->name); | |
if ($model = $this->bindEloquentModels($request, $instance, $parameter->name)) { | |
return $model; | |
} | |
return $instance; | |
} | |
if (isset($parameters[$parameter->name])) { | |
return $parameters[$parameter->name]; | |
} | |
if ($parameter->isDefaultValueAvailable()) { | |
return $parameter->getDefaultValue(); | |
} | |
throw new RuntimeException("No default value for {$parameter->name} in ".static::class); | |
} | |
protected function bindEloquentModels(Request $request, $instance, $name) | |
{ | |
if (!$instance instanceof UrlRoutable) { | |
return null; | |
} | |
$parameters = $request->argumentsWithoutNulls(); | |
if (!$parameterName = static::getEloquentParameterName($name, $parameters)) { | |
return null; | |
} | |
$parameterValue = $parameters[$parameterName]; | |
if (!$model = $instance->resolveRouteBinding($parameterValue)) { | |
throw (new ModelNotFoundException)->setModel(get_class($instance)); | |
} | |
return $model; | |
} | |
protected static function getEloquentParameterName($name, $parameters) | |
{ | |
if (array_key_exists($name, $parameters)) { | |
return $name; | |
} | |
if (array_key_exists($snakedName = Str::snake($name), $parameters)) { | |
return $snakedName; | |
} | |
if (array_key_exists('id', $parameters)) { | |
return 'id'; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment