如何在 symfony 中使用 api-platform 来编辑 post 数据?

How to use api-platform in symfony to edit the post data?

我是 symfony 的新手,但主要是 api-平台。所以我查看了 api-platform 以了解更多信息。我读了大部分,信息量很大。但我就是找不到一种方法来使用 openAPI 来获取编辑 post 数据。我也在使用 doctrine 和 SQLite

所以我所说的编辑 post 数据是什么意思。我安装了 api-platform 并使其正常工作(看起来像 this)。我可以在 url www.localhost/api 上使用我的 api 平台 POST 数据,然后在角色下 select POST 然后“尝试”。 我在教义上做了一个小table,所以我发给它的JSON是;

{
  "role": "string"
}

这样就可以了,它将数据添加到我的 SQLite 数据库中。但我想在 PHP 中编辑此数据。但我就是找不到如何检索此 JSON 并编辑我从 JSON.

获得的数据

我有的是;名为 Role 和 RoleRepository 的实体和存储库。我读到不需要控制器来使用 api-platform 编辑数据。但是我在任何地方都找不到如何编辑数据。

那么如何编辑从 JSON 中获取的数据?

编辑: 如果您想知道我的实体角色是什么样的;

<?php
namespace App\Entity;

use App\Repository\RoleRepository;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ApiResource()
 * @ORM\Entity(repositoryClass=RoleRepository::class)
 */
class Role
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $role;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getRole(): ?string
    {
        return $this->role;
    }

    public function setRole(string $role): self
    {
        $this->role = $role;

        return $this;
    }
}

和 RoleRepository

<?php

namespace App\Repository;

use App\Entity\Role;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @method Role|null find($id, $lockMode = null, $lockVersion = null)
 * @method Role|null findOneBy(array $criteria, array $orderBy = null)
 * @method Role[]    findAll()
 * @method Role[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class RoleRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Role::class);
    }

    // /**
    //  * @return Role[] Returns an array of Role objects
    //  */
    /*
    public function findByExampleField($value)
    {
        return $this->createQueryBuilder('r')
            ->andWhere('r.exampleField = :val')
            ->setParameter('val', $value)
            ->orderBy('r.id', 'ASC')
            ->setMaxResults(10)
            ->getQuery()
            ->getResult()
        ;
    }
    */

    /*
    public function findOneBySomeField($value): ?Role
    {
        return $this->createQueryBuilder('r')
            ->andWhere('r.exampleField = :val')
            ->setParameter('val', $value)
            ->getQuery()
            ->getOneOrNullResult()
        ;
    }
    */
}

Symfony 提供了所谓的内核事件,开发人员可以挂钩这些事件以直接处理 requests/responses,而无需编写特定的控制器或在数据到达控制器之前添加属性或更改某些内容。你可以找到这个 in the docs for the HttpKernel component.

API 平台通过挂钩这些事件来工作。您可以使用事件调度程序的调试命令看到这一点:

bin/console debug:event-dispatcher

这应该会打印出一个事件列表以及监听器对事件采取的行动,并且使用 api-platform 你应该有一些新的。或者,您可以查找 the list of provided event listeners in the api-platform docs。对您来说,ReadListener 和 WriteListener 可能是最相关的。您还可以查看 DeserializeListener,但它适用于所有 json 输入,因此您必须小心。

ReadListener 将使用 data providers. This is where you get your existing entity from, when you want to edit it. The WriteListener is how the new or edited data will be written to the database. This uses data persisters 从数据库中读取现有数据。

如果您想手动更改编辑实体的方式,您可能需要编写自己的 custom data persister or custom data provider

当您编写自己的数据持久化器时,您需要确保它支持您的实体。您几乎可以为此从文档中复制示例,只需更改 class 名称即可。然后 api-platform 将调用您的持久化器,您可以使用 var_dump 或 xdebug 检查您在 persist 方法中获得的值。第一个参数 $data 应该是您的实体,在第二个参数 $context 中您应该获得更多信息,例如使用了哪个 http 动词,我认为还有解码的 json 数据。

编写自己的提供程序和持久化程序可能有点棘手,通常不需要为每个实体都这样做(除非您不想使用标准的 getter 和 setter 方法在他们)。相反,您还可以通过添加类似于 @ApiResource 注释的元数据信息来修改实体的处理方式,例如用于验证或更改 class 的(反)序列化方式。此外,持久化器适用于已修改的实体,因此您的 json 数据已经过验证。没有什么能阻止您在那里进行额外的验证,但它可能是多余的,或者您可能认为为时已晚。简而言之,对于验证,您应该在 isX/hasX/getX-method 上写 your own validation constraints or use the ones provided by Symfony. For instance using something like the IsTrue constraint 可能是解决验证需求的好方法。