Skip to content

API Platform GraphQL Operation Provider Error #8112

Description

@dominik59

API Platform version(s) affected: 3.2.16

Bug Report

Issue Description:
We encountered an issue while utilizing an API platform test template to create a class. Initially, the class incorporated both REST and GraphQL operations, as demonstrated below:

<?php
namespace App\Entity\Enum;

use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\GraphQl\Query;
use ApiPlatform\Metadata\GraphQl\QueryCollection;
use ApiPlatform\Metadata\Operation;

#[Get(description: 'AvailabilityTypeEnum', provider: self::class.'::getCase')]
#[GetCollection(provider: self::class.'::getCases')]
#[Query(provider: self::class.'::getCase')]
#[QueryCollection(provider: self::class.'::getCases', paginationEnabled: false)]
enum AvailabilityTypeEnum: string {
    case Absent = 'Absent';
    case Present = 'Present';

    public function getId(): string {
        return $this->name;
    }

    public static function getCase(Operation $operation, array $uriVariables): AvailabilityTypeEnum {
        $name = $uriVariables['id'] ?? null;
        return \constant(self::class."::$name");
    }

    public static function getCases(): array {
        return self::cases();
    }
}

Understanding that our application purely relies on GraphQL operations, we decided to eliminate the REST annotations, leaving only the GraphQL-related ones:

#[Query(provider: self::class.'::getCase')]
#[QueryCollection(provider: self::class.'::getCases', paginationEnabled: false)]

Encountered Issue:
Post adjustments, fetching a single instance through GraphQL operation results in an error. The error indicates an issue tied to the Query provider being unrecognized, despite its explicit definition. This behavior is counterintuitive since removing the 'Query' operation should inhibit GraphQL operations, yet specifying it leads to provider-related errors.

Expected Behavior:
The system should seamlessly fetch a single entity or a collection based on GraphQL operations without necessitating the definition of REST-oriented providers (Get and GetCollection), especially when our usage context exclusively involves GraphQL.

Actual Behavior:
When attempting to fetch a single entity via GraphQL, the system fails, suggesting that a 'Get' provider is mandatory despite the active 'Query' provider. This not only contradicts the expected behavior but also limits our operations strictly to GraphQL, complicating the implementation process.

Steps to Reproduce:

  1. Create a class using the provided API platform test template.
  2. Remove REST-specific operations (Get, GetCollection).
  3. Attempt to fetch a single entity through the defined GraphQL operation.

Error Encountered:

{
  "errors": [
    {
      "message": "Provider not found on operation \"_api_/availability_type_enums/{id}{._format}_get\"",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "availabilityTypeEnum"
      ],
      "extensions": {
        "debugMessage": "Provider not found on operation \"_api_/availability_type_enums/{id}{._format}_get\"",
        "file": "/var/www/public/vendor/api-platform/core/src/State/CallableProvider.php",
        "line": 46,
        "trace": [
          {
            "file": "/var/www/public/vendor/api-platform/core/src/Symfony/Routing/IriConverter.php",
            "line": 98,
            "call": "ApiPlatform\\State\\CallableProvider::provide(instance of ApiPlatform\\Metadata\\NotExposed, array(1), array(5))"
          },
          {
            "file": "/var/www/public/vendor/api-platform/core/src/GraphQl/Resolver/Stage/ReadStage.php",
            "line": 95,
            "call": "ApiPlatform\\Symfony\\Routing\\IriConverter::getResourceFromIri('/api/availability_type_enums/Absent', array(5))"
          },
          {
            "file": "/var/www/public/vendor/api-platform/core/src/GraphQl/Resolver/Stage/ReadStage.php",
            "line": 53,
            "call": "ApiPlatform\\GraphQl\\Resolver\\Stage\\ReadStage::getItem('/api/availability_type_enums/Absent', array(5))"
          },
          {
            "file": "/var/www/public/vendor/api-platform/core/src/GraphQl/Resolver/Factory/ItemResolverFactory.php",
            "line": 58,
            "call": "ApiPlatform\\GraphQl\\Resolver\\Stage\\ReadStage::__invoke('App\\Entity\\Enum\\AvailabilityTypeEnum', 'App\\Entity\\Enum\\AvailabilityTypeEnum', instance of ApiPlatform\\Metadata\\GraphQl\\Query, array(6))"
          },
          {
            "file": "/var/www/public/vendor/api-platform/core/src/Symfony/GraphQl/Resolver/Factory/DataCollectorResolverFactory.php",
            "line": 37,
            "call": "ApiPlatform\\GraphQl\\Resolver\\Factory\\ItemResolverFactory::ApiPlatform\\GraphQl\\Resolver\\Factory\\{closure}(null, array(1), null, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
          },
          {
            "file": "/var/www/public/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
            "line": 714,
            "call": "ApiPlatform\\Symfony\\GraphQl\\Resolver\\Factory\\DataCollectorResolverFactory::ApiPlatform\\Symfony\\GraphQl\\Resolver\\Factory\\{closure}(null, array(1), null, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
          },
          {
            "file": "/var/www/public/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
            "line": 631,
            "call": "GraphQL\\Executor\\ReferenceExecutor::resolveFieldValueOrError(instance of GraphQL\\Type\\Definition\\FieldDefinition, instance of GraphQL\\Language\\AST\\FieldNode, instance of Closure, null, instance of GraphQL\\Type\\Definition\\ResolveInfo, null)"
          },
          {
            "file": "/var/www/public/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
            "line": 1317,
            "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField(GraphQLType: Query, null, instance of ArrayObject(1), array(1), null)"
          },
          {
            "file": "/var/www/public/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
            "line": 298,
            "call": "GraphQL\\Executor\\ReferenceExecutor::executeFields(GraphQLType: Query, null, array(0), instance of ArrayObject(1), null)"
          },
          {
            "file": "/var/www/public/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php",
            "line": 237,
            "call": "GraphQL\\Executor\\ReferenceExecutor::executeOperation(instance of GraphQL\\Language\\AST\\OperationDefinitionNode, null)"
          },
          {
            "file": "/var/www/public/vendor/webonyx/graphql-php/src/Executor/Executor.php",
            "line": 159,
            "call": "GraphQL\\Executor\\ReferenceExecutor::doExecute()"
          },
          {
            "file": "/var/www/public/vendor/webonyx/graphql-php/src/GraphQL.php",
            "line": 162,
            "call": "GraphQL\\Executor\\Executor::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, null, array(0), null, null)"
          },
          {
            "file": "/var/www/public/vendor/webonyx/graphql-php/src/GraphQL.php",
            "line": 96,
            "call": "GraphQL\\GraphQL::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, '{\n  availabilityTypeEnum(id: \"/api/availability_type_enums/Absent\") {\n    id\n  }\n}\n', null, null, array(0), null, null, null)"
          },
          {
            "file": "/var/www/public/vendor/api-platform/core/src/GraphQl/Executor.php",
            "line": 43,
            "call": "GraphQL\\GraphQL::executeQuery(instance of GraphQL\\Type\\Schema, '{\n  availabilityTypeEnum(id: \"/api/availability_type_enums/Absent\") {\n    id\n  }\n}\n', null, null, array(0), null, null, null)"
          },
          {
            "file": "/var/www/public/vendor/api-platform/core/src/GraphQl/Action/EntrypointAction.php",
            "line": 79,
            "call": "ApiPlatform\\GraphQl\\Executor::executeQuery(instance of GraphQL\\Type\\Schema, '{\n  availabilityTypeEnum(id: \"/api/availability_type_enums/Absent\") {\n    id\n  }\n}\n', null, null, array(0), null)"
          },
          {
            "file": "/var/www/public/vendor/symfony/http-kernel/HttpKernel.php",
            "line": 163,
            "call": "ApiPlatform\\GraphQl\\Action\\EntrypointAction::__invoke(instance of Symfony\\Component\\HttpFoundation\\Request)"
          },
          {
            "file": "/var/www/public/vendor/symfony/http-kernel/HttpKernel.php",
            "line": 74,
            "call": "Symfony\\Component\\HttpKernel\\HttpKernel::handleRaw(instance of Symfony\\Component\\HttpFoundation\\Request, 1)"
          },
          {
            "file": "/var/www/public/vendor/symfony/http-kernel/Kernel.php",
            "line": 184,
            "call": "Symfony\\Component\\HttpKernel\\HttpKernel::handle(instance of Symfony\\Component\\HttpFoundation\\Request, 1, true)"
          },
          {
            "file": "/var/www/public/vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php",
            "line": 35,
            "call": "Symfony\\Component\\HttpKernel\\Kernel::handle(instance of Symfony\\Component\\HttpFoundation\\Request)"
          },
          {
            "file": "/var/www/public/vendor/autoload_runtime.php",
            "line": 29,
            "call": "Symfony\\Component\\Runtime\\Runner\\Symfony\\HttpKernelRunner::run()"
          },
          {
            "file": "/var/www/public/public/index.php",
            "line": 5,
            "function": "require_once('/var/www/public/vendor/autoload_runtime.php')"
          }
        ]
      }
    }
  ],
  "data": {
    "availabilityTypeEnum": null
  }
}

This issue suggests a potential misunderstanding or misconfiguration in handling GraphQL operations within the system, necessitating a closer examination and resolution to align with the anticipated outcome.

Post scriptum:
When Get related annotations are defined, everything functions as intended. However, an issue arises upon solely relying on GraphQL operations after removing REST-specific annotations (Get, GetCollection). This leads to an unexpected error when fetching a single entity using GraphQL, pointing to a discrepancy between expected and actual behavior concerning operation providers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions