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

API Platform GraphQL Operation Provider Error #2668

Open
dominik59 opened this issue Mar 20, 2024 · 0 comments
Open

API Platform GraphQL Operation Provider Error #2668

dominik59 opened this issue Mar 20, 2024 · 0 comments

Comments

@dominik59
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant