# Automated Code Refactoring with Rector
Lighthouse provides Rector (opens new window) rules to automate code migrations and enforce conventions.
# RootResolverSignatureRector
Ensures that root resolver __invoke methods match the Lighthouse calling convention.
Root resolvers receive null as their first argument because they have no parent value.
This rule normalizes signatures to explicitly reflect that.
# Setup
Add the rule to your rector.php configuration:
use Nuwave\Lighthouse\Rector\RootResolverSignatureRector;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(RootResolverSignatureRector::class);
// Required: Larastan bootstrap makes config() available
$rectorConfig->bootstrapFiles([
__DIR__ . '/vendor/larastan/larastan/bootstrap.php',
]);
};
# What it does
The examples below use
null $root(PHP 8.2+). On PHP 8.0/8.1, the rule producesmixed $rootinstead.
Adds the missing $root parameter when only array $args is present:
// Before
public function __invoke(array $args): mixed {}
// After
public function __invoke(null $root, array $args): mixed {}
Fixes the root parameter type when it is typed incorrectly:
// Before
public function __invoke(User $root, array $args): mixed {}
// After
public function __invoke(null $root, array $args): mixed {}
Removes a useless single root parameter when only a non-array root is passed:
// Before
public function __invoke(mixed $root): mixed {}
// After
public function __invoke(): mixed {}
Normalizes parameter names via the paramNames option (see Configuration).
# Configuration
Optionally configure preferred parameter names:
$rectorConfig->ruleWithConfiguration(RootResolverSignatureRector::class, [
'paramNames' => ['_', 'args', 'context', 'resolveInfo'],
]);
Use null at any position to skip renaming that parameter:
$rectorConfig->ruleWithConfiguration(RootResolverSignatureRector::class, [
'paramNames' => [null, null, 'context', 'resolveInfo'],
]);
# Known Limitation
The rule assumes every class with an __invoke method found under the resolver directories (e.g. App\GraphQL\Queries, App\GraphQL\Mutations) is a root resolver.
Classes that are not root resolvers — such as nested field resolvers that receive a parent model as their first argument — will be incorrectly rewritten.
Mitigations:
- Move non-root-resolver classes out of the resolver directories (preferred — they do not belong there).
- Add the affected files to the Rector skip list (opens new window).