问题描述
我从 API 平台开始,我必须重构一个没有使用 API 平台的旧 API。我正在使用 Symfony 5 和 Doctrine,我公开了带有 @Api Platform 注释的实体,我在 API 文档上看到了 CRUD 操作。但是我要自定义几个操作,遇到了一些困难。
实体:
/**
* Parcsportif
* @ApiResource(
* collectionoperations={"get"},* itemOperations={"get"})
*
* @ORM\Table(name="parcSportif",indexes={@ORM\Index(name="index_numSite",columns={"numSite"})})
* @ORM\Entity
*/
class Parcsportif
{
/**
* @var int
* @ORM\Column(name="numParc",type="integer",nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $numparc;
/**
* @var int
* @ORM\Column(name="numSite",nullable=false)
*/
private $numsite = '0';
// others attributes and getters and setters
Api平台生成的路由是:
- /api/parcsportifs : GET 集合
- /api/parcsportifs/{numparc} : 获取项目
但我想像这样修改它们:
所以我像这样改变了实体:
**
* Parcsportif
* @ApiResource(
* collectionoperations={
* "get"={
* "method"="GET",* "path"="/listeEquipementsClient/{numsite}",* "openapi_context" = {
* "parameters" = {
* {
* "name" = "numsite",* "in" = "path",* "description" = "numéro site",* "required" = true,* "schema"={
* "type" : "integer"
* },* "style"="simple"
* }
* }
* },* "controller" = ListeEquipementsController::class
* }
* },* itemOperations={"get"={"path"="/informationEquipement/{numparc}"}}
* )
上面的控制器是:
class ListeEquipementsController
{
private $parcSportifRepository;
public function __construct(ParcSportifRepository $parcSportifRepository)
{
$this->parcSportifRepository = $parcSportifRepository;
}
public function __invoke($numsite): iterable
{
return $this->parcSportifRepository->getListeEquipementsParNumSite($numsite);
}
}
以及实体的存储库:
class ParcSportifRepository extends ServiceEntityRepository
{
private $em;
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry,Parcsportif::class);
$this->em = $this->getEntityManager();
}
public function getListeEquipementsParNumSite($numSite): iterable
{
return $this->findBy([
"numsite" => $numSite,]);
}
}
所以路由 2) 操作“GET item”工作正常,但是当我在 Postman 上调用路由 1) 时出现以下错误:
“无法为“App\Entity\Parcsportif”生成 IRI。”
我不明白。
我怎样才能找出问题所在?
解决方法
将 /listeEquipementsClient/{numsite}
指定为路径时,您是在告诉 API 平台 numsite
是您的资源的 identifier。不仅 numsite
不是资源标识符(这是 numparc
,导致您遇到的错误),集合 GET 操作不应该期望 url path slugs 作为过滤器参数,而是期望查询参数:
/parcsportifs?numsite=123
这应该过滤 Parcsportif
集合中 numsite
值为 123
的资源,并且可以通过向 @ApiFilter
提供 Parcsportif::$numsite
注释来实现属性:
/**
* @var int
* @ORM\Column(name="numSite",type="integer",nullable=false)
* @ApiFilter(
* SearchFilter::class,* properties={
* "numsite": "exact"
* }
* )
*/
private $numsite = '0';
如果您真的想实现帖子中描述的端点(使用 numsite
作为资源标识符),您将必须实现自定义资源和支持 numsite
的 data provider此资源的标识符。