Skip to content

Query complexity is missing on fields included by fragments #785

Open
@jacor84

Description

@jacor84

Description

QueryComplexity rule implements visitor in such a way that results in missing field definitions when non-inline fragments are used and defined after the operation (as it usually is). If you reverse the order and put fragments first, all works fine.

Reproduction path

A simple reproduction script is attaching a custom complexity closure to ExampleType fields. They are included using a fragment, and should result in a complexity error. However, no such error is triggered, because these field definitions are missing from fieldNodeAndDefs, and a default complexity function is used on them.

<?php

use GraphQL\GraphQL;
use GraphQL\Utils\BuildSchema;
use GraphQL\Validator\Rules\QueryComplexity;

require_once __DIR__ . '/vendor/autoload.php';

$exampleSchema = '
  type Query {
    example: ExampleType
  }

  type ExampleType {
    a: Int
    b: String
  }
';

$query = '
  query {
    ...exampleFragment
  }

  fragment exampleFragment on Query { # values from default complexity fn
    example { # 2 + 1
      a
      b
    }
  }
';

$typeConfigDecorator = function (array $typeConfig): array {
    if ($typeConfig['name'] !== 'ExampleType') {
        return $typeConfig;
    }
    $typeConfig['fields'] = static function () use ($typeConfig) {
        $fieldDefinitions = $typeConfig['fields']();
        foreach ($fieldDefinitions as $fieldName => &$fieldDefinition) {
            $fieldDefinition['complexity'] = function ($childComplexity) {
                return $childComplexity + 1000;
            };
        }

        return $fieldDefinitions;
    };

    return $typeConfig;
};

$schema = BuildSchema::build($exampleSchema, $typeConfigDecorator);

$queryComplexity = new QueryComplexity(100);

$result = GraphQL::executeQuery(
    $schema,
    $query,
    null,
    null,
    null,
    null,
    null,
    [
        $queryComplexity
    ]
);
echo json_encode($result->toArray(), JSON_PRETTY_PRINT);

Put it in an empty directory, call composer require webonyx/graphql-php and run php complexity.php.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions