为什么我在使用 Api-Platform 时得到 "No item route associated with the type"?

Why do I get "No item route associated with the type" when using Api-Platform?

我的项目是在 Symfony 5 和 API-Platform 中构建的,以便从 JS 客户端使用它。在这种情况下,我有一个 Question 实体与 Answer 实体相关(分别为一对多)。

每当我尝试调用 /api/questions/api/answers 时,我都会收到此错误消息:“没有与类型“App\Entity\Answer”关联的项目路由”:

为了 API 资源,这是我用 maker bundle 配置的:

- App\Entity\Question:

/**
 * @ORM\Entity(repositoryClass=QuestionRepository::class)
 * @ApiResource
 * @ApiFilter(SearchFilter::class, properties={"status": "exact"})
 */
class Question
{
    // ...
    /**
     * @ORM\ManyToOne(targetEntity=User::class, inversedBy="questions")
     * @ORM\JoinColumn(nullable=false)
     */
    private $owner;

    // ... 

    /**
     * @ORM\OneToMany(targetEntity=Answer::class, mappedBy="question", orphanRemoval=true)
     */
    private $answers;

    // ...

    /**
     * @return Collection|Answer[]
     */
    public function getAnswers(): Collection
    {
        return $this->answers;
    }

    public function addAnswer(Answer $answer): self
    {
        if (!$this->answers->contains($answer)) {
            $this->answers[] = $answer;
            $answer->setQuestion($this);
        }

        return $this;
    }

    public function removeAnswer(Answer $answer): self
    {
        if ($this->answers->contains($answer)) {
            $this->answers->removeElement($answer);
            // set the owning side to null (unless already changed)
            if ($answer->getQuestion() === $this) {
                $answer->setQuestion(null);
            }
        }

        return $this;
    }

    // ...
}

- App\Entity\Answer:

/**
 * @ORM\Entity(repositoryClass=AnswerRepository::class)
 * @ApiResource
 */
class Answer
{
    // ...
    
    /**
     * @ORM\ManyToOne(targetEntity=Question::class, inversedBy="answers")
     * @ORM\JoinColumn(nullable=false)
     * @Assert\NotBlank
     */
    private $question;

    // ...

    public function getQuestion(): ?Question
    {
        return $this->question;
    }

    public function setQuestion(?Question $question): self
    {
        $this->question = $question;

        return $this;
    }
   
    // ...
}

不确定这是否与此问题相关:我在 api_platform.yaml:

上配置了 config/api_platform/resources.yaml
App\Entity\Answer:
  attributes:
    security: 'is_granted("ROLE_USER")'
    security_message: 'Only the authenticated user can see answers'
  collectionOperations:
    get:
      security: 'is_granted("ROLE_USER")'
      security_message: 'Only the authenticated user can get answers'
    post:
      security: 'is_granted("ROLE_USER")'
      security_message: 'Only the authenticated user can save answers'
  itemOperations:
      put:
        security: 'is_granted("ROLE_ADMIN") or object.owner == user'
        security_message: 'Only the authenticated user or administrators can update answers'
      delete:
        security: 'is_granted("ROLE_ADMIN")'
        security_message: 'Only administrators can delete answers'

App\Entity\Question:
  attributes:
    security: 'is_granted("ROLE_USER")'
    security_message: 'Only the authenticated user can see questions'
  collectionOperations:
    get:
      security: 'is_granted("ROLE_ADMIN")'
      security_message: 'Only the authenticated user or administrators can get questions'
    post:
      security: 'is_granted("ROLE_USER")'
      security_message: 'Only the authenticated user can save questions'
  itemOperations:
      get:
        security: 'is_granted("ROLE_ADMIN") or object.owner == user'
        security_message: 'Only the authenticated user or administrators can get questions'
      put:
        security: 'is_granted("ROLE_ADMIN") or object.owner == user'
        security_message: 'Only the authenticated user or administrators can update questions'
      delete:
        security: 'is_granted("ROLE_ADMIN")'
        security_message: 'Only administrators can delete questions'

Swagger UI 显示有关 QuestionAnswer 实体资源的信息:

这就是 debug:route 显示的关于 Answer:

  api_answers_get_collection                      GET        ANY      ANY    /api/answers.{_format}
  api_answers_post_collection                     POST       ANY      ANY    /api/answers.{_format}
  api_answers_put_item                            PUT        ANY      ANY    /api/answers/{id}.{_format}
  api_answers_delete_item                         DELETE     ANY      ANY    /api/answers/{id}.{_format}

这里有什么问题?

TLDR:

对于所有资源,您需要有基本的 **item ** GET /resource/{id} 路由。



错误信息非常明确:

No item route associated with the type "App\Entity\Answer"

如果您检查 Answer 的资源定义,您将看到:

itemOperations:
      put:
        security: 'is_granted("ROLE_ADMIN") or object.owner == user'
        security_message: 'Only the authenticated user or administrators can update answers'
      delete:
        security: 'is_granted("ROLE_ADMIN")'
        security_message: 'Only administrators can delete answers'

所以你基本上只有 deleteupdate 路线,但没有基本的项目检索路线 (GET /api/answers/123 ).通过显式定义路由,无论你没有定义什么路由,你 disable.

API 文档的输出证实了这一点:

否则,不可能获得资源的有效 IRI。如果没有资源的有效 GET 路由,系统无法为每个资源项生成 URL,并且由于那些 URLs/IRIs 被用作 标识符 系统,这些应该始终被定义。

你只需要添加返回物品路由的配置:

itemOperations:
      put:
        security: 'is_granted("ROLE_ADMIN") or object.owner == user'
        security_message: 'Only the authenticated user or administrators can update answers'
      delete:
        security: 'is_granted("ROLE_ADMIN")'
        security_message: 'Only administrators can delete answers'
      get:
        security: 'is_granted("ROLE_USER")'
        security_message: 'Only the authenticated user can get answers'

当您有一个具有相同名称的实体但另一个实体没有 @ApiResource 设置时,也可能会导致这种情况。

喜欢 src/Entity/Answer 中的答案和 src/Entity/Questions/Answer 中的答案