ApiPlatform 实体关系 iri 和 schema

ApiPlatform entity relation iri and schema

我不知道如何实现这个目标: 我也想在 GET 请求中将对象表示与相关实体作为 json 对象,而我只想在父对象 POST 请求中发送 iri

/**
 * @ORM\Entity(repositoryClass=CustomerRepository::class)
 * @ApiResource
 */
class Customer
{
    /**
     * @var int|null
     *
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @ApiProperty(
     *     identifier=false,
     *     description="ID univoco del cliente generato da un'operazione di POST"
     * )
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="codice_cliente", type="string", length=20, unique=true)
     * @ApiProperty(
     *     identifier=true,
     *     description="Codice identificativo del cliente.<br>Si tratta di un codice univoco che identifica il cliente all'interno dell'azienda di riferimento"
     * )
     */
    private $codiceCliente;

    /**
     * @var string|null
     *
     * @ORM\Column(name="ragione_sociale", type="string", length=50, nullable=true)
     * @ApiProperty(description="Denominazione ufficiale del cliente")
     */
    private $ragioneSociale;

    /**
     * @var string|null
     *
     * @ORM\Column(name="nome", type="string", length=50, nullable=true)
     * @ApiProperty(description="Nome anagrafico del cliente")
     */
    private $nome;

    /**
     * @var string|null
     *
     * @ORM\Column(name="cognome", type="string", length=50, nullable=true)
     * @ApiProperty(description="Cognome anagrafico del cliente")
     */
    private $cognome;

    /**
     * @var string|null
     *
     * @ORM\Column(name="codice_fiscale", type="string", length=16, nullable=true)
     * @ApiProperty(description="Codice fiscale del cliente.<br>Può corrispondere a `partitaIva` in caso di azienda.")
     */
    private $codiceFiscale;

    /**
     * @var string|null
     *
     * @ORM\Column(name="partita_iva", type="string", length=11, nullable=true)
     * @ApiProperty(description="Partita Iva del cliente in caso di azienda.<br>È un valore numerico di 11 cifre.")
     */
    private $partitaIva;

    /**
     * @var CustomerCategory
     *
     * @ORM\ManyToOne(targetEntity=CustomerCategory::class)
     * @ORM\JoinColumn(name="categoria_id", referencedColumnName="codice", nullable=false)
     */
    private $categoria;

    /**
     * @return int|null
     */
    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getCodiceCliente(): ?string
    {
        return $this->codiceCliente;
    }

    /**
     * @param string $codiceCliente
     *
     * @return Customer
     */
    public function setCodiceCliente(string $codiceCliente): Customer
    {
        $this->codiceCliente = $codiceCliente;
        return $this;
    }

    /**
     * @return string|null
     */
    public function getRagioneSociale(): ?string
    {
        return $this->ragioneSociale;
    }

    /**
     * @param string|null $ragioneSociale
     *
     * @return Customer
     */
    public function setRagioneSociale(?string $ragioneSociale): Customer
    {
        $this->ragioneSociale = $ragioneSociale;
        return $this;
    }

    /**
     * @return string|null
     */
    public function getNome(): ?string
    {
        return $this->nome;
    }

    /**
     * @param string|null $nome
     *
     * @return Customer
     */
    public function setNome(?string $nome): Customer
    {
        $this->nome = $nome;
        return $this;
    }

    /**
     * @return string|null
     */
    public function getCognome(): ?string
    {
        return $this->cognome;
    }

    /**
     * @param string|null $cognome
     *
     * @return Customer
     */
    public function setCognome(?string $cognome): Customer
    {
        $this->cognome = $cognome;
        return $this;
    }

    /**
     * @return string|null
     */
    public function getCodiceFiscale(): ?string
    {
        return $this->codiceFiscale;
    }

    /**
     * @param string|null $codiceFiscale
     *
     * @return Customer
     */
    public function setCodiceFiscale(?string $codiceFiscale): Customer
    {
        $this->codiceFiscale = $codiceFiscale;
        return $this;
    }

    /**
     * @return string|null
     */
    public function getPartitaIva(): ?string
    {
        return $this->partitaIva;
    }

    /**
     * @param string|null $partitaIva
     *
     * @return Customer
     */
    public function setPartitaIva(?string $partitaIva): Customer
    {
        $this->partitaIva = $partitaIva;
        return $this;
    }

    public function getCategoria(): ?CustomerCategory
    {
        return $this->categoria;
    }

    public function setCategoria(?CustomerCategory $categoria): self
    {
        $this->categoria = $categoria;

        return $this;
    }

}

/**
 * @ORM\Entity(repositoryClass=CustomerCategoryRepository::class)
 * @ApiResource()
 */
class CustomerCategory
{
    /**
     * @var string
     *
     * @ORM\Id
     * @ORM\Column(type="string", length=10)
     * @ApiProperty(identifier=true,
     *     description="Codice identificativo della categoria")
     */
    private $codice;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=100, nullable=true)
     * @ApiProperty(description="Descrizione del codice di identificazione")
     */
    private $descrizione;

    public function getCodice(): ?string
    {
        return $this->codice;
    }

    public function setCodice(string $codice): self
    {
        $this->codice = $codice;

        return $this;
    }

    public function getDescrizione(): ?string
    {
        return $this->descrizione;
    }

    public function setDescrizione(?string $descrizione): self
    {
        $this->descrizione = $descrizione;

        return $this;
    }
}

因此,当我获得客户时,我希望 $categoria 属性 成为

{
    codice: "10"
    descrizione: "Test"
}

当我 POST/PUT/PATCH 一个客户时,我想将 CustomerCategory 称为 ID 的 IRI,因为在这种情况下我没有级联

{
  "codiceCliente": "string",
  "ragioneSociale": "string",
  "nome": "string",
  "cognome": "string",
  "codiceFiscale": "string",
  "partitaIva": "string",
  "categoria": "/api/customer_categories/10"
}

我也想在 OPEN API 文档中有正确的表示

您可以使用 Serialization Group 获得此类结果,除了将 @id 和 @type 添加到 Customer 和 $categoria 属性(API 平台自动添加他们)。

首先将以下内容添加到您的两个实体中:

use Symfony\Component\Serializer\Annotation\Groups;

仅为客户的获取操作配置序列化组:

/**
 * @ORM\Entity(repositoryClass=CustomerRepository::class)
 * @ApiResource(
 *     itemOperations={
 *          "get"={
 *              "normalization_context"={"groups"={"customer:get"}}
 *          },
 *          "patch",
 *          "put",
 *          "delete"
 *     },
 *     collectionOperations={
 *         "get"={
 *              "normalization_context"={"groups"={"customer:get"}}
 *          },
 *          "post"
 *     }
 * )
 */
class Customer
//...

然后将@Groups({"customer:get"}) 添加到除$id 之外的所有Customer 属性的文档块中,包括$categoria。我这里只举一个例子:

/**
 * @var string|null
 *
 * @ORM\Column(name="ragione_sociale", type="string", length=50, nullable=true)
 * @ApiProperty(description="Denominazione ufficiale del cliente")
 * @Groups({"customer:get"})
 */
private $ragioneSociale;

同时将@Groups({"customer:get"}) 添加到 CustomerCategory 的 $codice 和 $descrizione 的文档块中。

这应该可以解决问题并保持 post、put 和 patch 操作不变(期望并仅返回 $categoria 的 iri)。它应该自动在 OPEN API 文档上给出正确的表示。

提示:我的 tutorial 的分支 chapter4-api 的自述文件也包含添加序列化组的说明,两个实体与您的相关,结果代码在分支 chapter5-api.