Jack Skeletron
Jack Skeletron

Reputation: 1501

ApiPlatform entity relation iri and schema

I cannot figure out how to reach this goal: I want to have the object representation in a GET request with the related entity as json object too, while i want to send just the iri in a POST request of the parent object

/**
 * @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;
    }
}

So when i GET the Customer i want the $categoria property to be

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

While when i POST/PUT/PATCH a Customer i want to refer to the CustomerCategory as the IRI of the ID as i don't have cascade persists in this case

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

I want also to have the correct representation on the OPEN API docs

Upvotes: 0

Views: 980

Answers (1)

MetaClass
MetaClass

Reputation: 1428

You can get such results using a Serialization Group, except for the @id and @type being added to both Customer and to the $categoria property (API Platform automatically adds them).

First add the following to both your Entities:

use Symfony\Component\Serializer\Annotation\Groups;

To configure a Serialization Group only for the get operations of Customer:

/**
 * @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
//...

And then add @Groups({"customer:get"}) to the doc blocks of all props of Customer except $id, including $categoria. I only give one example here:

/**
 * @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;

Also add @Groups({"customer:get"}) to the doc blocks of $codice and $descrizione of CustomerCategory.

This should do the trick and leave the post, put and patch operations unchanged (expecting and returning just the iri of $categoria). It should automatically give a correct representation on the OPEN API docs.

Tip: The readme of branch chapter4-api of my tutorial also contains instructions for adding Serialization Groups two Entities related like yours, and the resulting code is in branch chapter5-api.

Upvotes: 1

Related Questions