微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

API 平台 - 如何创建自定义集合操作 (GET)?

如何解决API 平台 - 如何创建自定义集合操作 (GET)?

我从 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} : 获取项目

但我想像这样修改它们:

  1. /api/listeEquipements/{numsite} :通过 'numsite' 属性获取集合
  2. /api/informationEquipement/{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 作为资源标识符),您将必须实现自定义资源和支持 numsitedata provider此资源的标识符。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。