Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the default field resolver #2191

Open
spawnia opened this issue Aug 4, 2022 · 2 comments
Open

Change the default field resolver #2191

spawnia opened this issue Aug 4, 2022 · 2 comments
Labels
discussion Requires input from multiple people

Comments

@spawnia
Copy link
Collaborator

spawnia commented Aug 4, 2022

What problem does this feature proposal attempt to solve?

Community feedback has shown that the default resolver from webonyx/graphql-php may not be optimally suited for a Laravel application and there is potential for improvement.

Because the default resolver is called very often, we have to consider performance.

Which possible solutions should be considered?

Given Eloquent models are probably the most common returned data type, we could optimize for them.

Changing the default resolver is documented here, but could perhaps be simplified through the config.

@spawnia spawnia added the discussion Requires input from multiple people label Aug 4, 2022
@olivernybroe
Copy link
Collaborator

I think this could be a great idea and something that would improve performance greatly.

I have however tried to also submit a pr to Laravel with the issue itself as webonyx/graphql is prob. not the only package relying on ArrayAccess being implemented correctly. laravel/framework#45976

@pyrou
Copy link
Collaborator

pyrou commented Mar 2, 2023

I am using for while now the following "DefaultResolver":

<?php

namespace App\GraphQL\Resolvers;

use ArrayAccess;
use Closure;
use GraphQL\Type\Definition\ResolveInfo;
use Illuminate\Support\Str;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;

class DefaultResolver
{
    public function __invoke(mixed $parent, $args, GraphQLContext $context, ResolveInfo $resolveInfo): mixed
    {
        $fieldName = $resolveInfo->fieldName;
        $snakeFieldName = Str::snake($fieldName);
        
        $value = $this->getFieldValue($parent, $fieldName);
        
        if ($value === null && $snakeFieldName !== $fieldName) {
            // Give a chance to resolve field using the snake case
            $value = $this->getFieldValue($parent, $snakeFieldName);
        }

        return $value instanceof Closure ? $value($parent, $args, $context, $resolveInfo) : $value;
    }

    protected function getFieldValue(mixed $parent, string $fieldName): mixed
    {
        if (is_array($parent) || $parent instanceof ArrayAccess) {
            return $parent[$fieldName] ?? null;
        }
        if (is_object($parent) && isset($parent->{$fieldName})) {
            return $parent->{$fieldName};
        }

        return null;
    }
}

It is plugged into lighthouse with Executor::setDefaultFieldResolver($defaultResolver);

It mainly address the @rename overuse.

If this get you some idea for a new default resolver on Lighthouse 6 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Requires input from multiple people
Projects
None yet
Development

No branches or pull requests

3 participants