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

Lazy field definitions are eager loaded when schema has no type loader #1093

Closed
NikolaiEngel opened this issue Mar 28, 2022 · 1 comment · Fixed by #1104
Closed

Lazy field definitions are eager loaded when schema has no type loader #1093

NikolaiEngel opened this issue Mar 28, 2022 · 1 comment · Fixed by #1104
Labels

Comments

@NikolaiEngel
Copy link

NikolaiEngel commented Mar 28, 2022

Hey,

i have created the following sample code to prove that the lazy loading feature does not work as desired.

If I query the field Test2, the class TestInvokable is created despite lazy loading. This has the consequence that a lot of dependencies have to be resolved, which are not necessary for the query. In this example this is illustrated by a sleep of 3 seconds.

I have also created an alternative TestCase in which it works. When I set up the Schema as in the linked page: https://webonyx.github.io/graphql-php/schema-definition-language/, the TestInvokable class is not created. Since there are two ways to use the GraphQL, I would like to have this feature also for the scenario described below.

// index.php
$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);
$query = $input['query'] ?? '';
$variableValues = $input['variables'] ?? null;
$operationName = $input['operationName'] ?? null;

$queryType = $container->get(QueryType::class);

$schema = new Schema(['query' => $queryType]);

// execute query
$result = GraphQL::executeQuery(
    $schema,
    $query,
    null,
    null,
    $variableValues,
    $operationName
)->toArray();

echo json_encode($result);
// QueryType.php
class QueryType extends ObjectType
{

    private const TEST1_FIELD = 'Test1';
    private const TEST2_FIELD = 'Test2';

    private ContainerInterface $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        parent::__construct($this->getConfig());
    }

    public function getConfig(): array
    {
        return [
            'fields' => [
                self::TEST1_FIELD => fn() => [
                    'description' => 'My Test Field 1',
                    'type' => self::string(),
                    'resolve' => $this->container->get(TestInvokable::class),
                ],
                self::TEST2_FIELD => fn() => [
                    'description' => 'My Test Field 2',
                    'type' => self::string(),
                    'resolve' => fn() => 'Hello World',
                ]
            ],
        ];
    }
}
// Test Invokable
class TestInvokable
{

    public function __construct()
    {
        // Heavy dependencies
        sleep(3);
    }

    public function __invoke($source, array $args): string
    {
        return 'FooBar';
    }
}

Linked issue is a feature request to create a DI container known to GraphQL to use invokable classes for resolution. #1088

@spawnia
Copy link
Collaborator

spawnia commented Apr 7, 2022

Got it, I can reproduce the issue in a test case. The problem is that the schema is always loader eagerly when no type loader is present. I am trying to fix this in #1104

@spawnia spawnia changed the title Lazy Field Definition does not always work Lazy Field Definitions are eager loaded when schema has no type loader Apr 14, 2022
@spawnia spawnia changed the title Lazy Field Definitions are eager loaded when schema has no type loader Lazy field definitions are eager loaded when schema has no type loader Apr 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants