为什么我在使用 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 显示有关 Question
和 Answer
实体资源的信息:
这就是 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'
所以你基本上只有 delete 和 update 路线,但没有基本的项目检索路线 (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 中的答案
我的项目是在 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 显示有关 Question
和 Answer
实体资源的信息:
这就是 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'
所以你基本上只有 delete 和 update 路线,但没有基本的项目检索路线 (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 中的答案