api-platform icon indicating copy to clipboard operation
api-platform copied to clipboard

AnnotationResourceFilterMetadataFactory - Resource not found

Open remif25 opened this issue 4 years ago • 1 comments

API Platform: 2.6.2 PHP: 8.0.0

Description
API platform return the error bellow when I try to execute the cli : php bin/console api:openapi:export :

[critical] Error thrown while running command "api:openapi:export". Message: "Resource "\App\Entity\Question" not found."

Of course my file src\Entity\Question.php exist and here it's the beginning :

<?php

namespace App\Entity;

use JsonSerializable;

class Question implements JsonSerializable
{
 //...rest of the class
}

I really spend hours to understand where the problem come from but I didn't find. However, I find a dirty solution to fix it to unlock the situation, by added this lines in the function create in file vendor/api-platform/core/src/Metadata/Resource/Factory/AnnotationResourceFilterMetadataFactory.php :

public function create(string $resourceClass): ResourceMetadata
    {
        $parentResourceMetadata = null;
        if ($this->decorated) {
            try {
                $parentResourceMetadata = $this->decorated->create($resourceClass);
            } catch (ResourceClassNotFoundException $resourceNotFoundException) {
               /* --------------- Start : added lines --------------- */
                try {
                    $parentResourceMetadata = $this->decorated->create(substr($resourceClass, 1));
                } catch (ResourceClassNotFoundException $resourceNotFoundException) {
                    // Ignore not found exception from decorated factories
                }
              /* --------------- End : added lines --------------- */
            }
        }

        if (null === $parentResourceMetadata) {
            return $this->handleNotFound($parentResourceMetadata, $resourceClass);
        }

        try {
            $reflectionClass = new \ReflectionClass($resourceClass);
        } catch (\ReflectionException $reflectionException) {
            return $this->handleNotFound($parentResourceMetadata, $resourceClass);
        }

        $filters = array_keys($this->readFilterAnnotations($reflectionClass, $this->reader));

        if (!$filters) {
            return $parentResourceMetadata;
        }

        $parentFilters = $parentResourceMetadata->getAttribute('filters', []);

        if ($parentFilters) {
            $filters = array_merge($parentFilters, $filters);
        }

        $attributes = $parentResourceMetadata->getAttributes();

        if (!$attributes) {
            $attributes = [];
        }

        return $parentResourceMetadata->withAttributes(array_merge($attributes, ['filters' => $filters]));
    }

How to reproduce
I don't know if those few elements are enough to describe the problem, but if necessary I can give access to the Github of the current project to reproduce the bug.

Additional Context config\packages\api_platform.yml

api_platform:
  show_webby: false
  mapping:
    paths : ['%kernel.project_dir%/config/packages/api_platform']
  patch_formats:
    json: ['application/merge-patch+json']
  swagger:
    versions: [3]
  formats:
    json:
      mime_types: [ 'application/json' ]
    jsonld:
      mime_types: [ 'application/ld+json' ]
  exception_to_status:
    # The 4 following handlers are registered by default, keep those lines to prevent unexpected side effects
    Symfony\Component\Serializer\Exception\ExceptionInterface: 400 # Use a raw status code (recommended)
    ApiPlatform\Core\Exception\InvalidArgumentException: 'HTTP_BAD_REQUEST' # Or a `Symfony\Component\HttpFoundation\Response`'s constant
    ApiPlatform\Core\Exception\FilterValidationException: 400
    Doctrine\ORM\OptimisticLockException: 409

  collection:
    pagination:
      enabled: false

config\packages\api_platform\question.yml

resources:
  App\Entity\Question:
    properties:
      id:
        identifier: true
      questions:
        readableLink: true
        writableLink: true
    collectionOperations: []
    itemOperations:
      get_preventions_questions:
        read: false
        method: GET
        path: "/Preventions"
        controller: App\Controller\PreventionQuestions
        swagger_context:
          consumes: "application/json"
          produces: "application/json"
          parameters:
            - name: SessionId
              in: header
              required: true

Thank you for you help.

remif25 avatar Feb 11 '21 21:02 remif25

I had the same problem and it was because of defining a relation as ApiSubresource which the target entity wasn't ApiResource

aalinia avatar Jul 25 '22 09:07 aalinia