Loic H
Loic H

Reputation: 348

Api-platform PUT operation with denormalization_context groups on an itemOperations not working

I have 2 entities:

I wanted to retrieve only words for itemOperation and not for collectionOperations so i added a group GET "item_words.read" and for PUT denormalization_context.

It is perfectly working for GET operation, for some reason the PUT operation is not giving me the "words" subresource.

GET :

enter image description here

PUT :

enter image description here

Here is my code :

Item

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiSubresource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;
use App\Controller\FileUploadController;
use Symfony\Component\Validator\Constraints as Assert;
use App\Controller\ItemVocabularyController;
use Symfony\Component\Serializer\Annotation\Groups;
use Gedmo\Mapping\Annotation as Gedmo;


/**
 * @ApiResource(
 *     normalizationContext={"groups"={"item.read"}},
 *     denormalizationContext={"groups"={"item.write"}},
 *     collectionOperations={"get", "post"},
 *     attributes={"order"={"words.value": "ASC"}},
 *     itemOperations={
 *          "get"={
 *              "normalization_context"={"groups"={"item.read","item_words.read"}},
 *          },
 *          "put"={
 *              "denormalization_context"={"groups"={"item.write","item_words.write"}},
 *          },
 *         "delete",
 *         "getItemVocabulary"={
 *                   "method"="GET",
 *                   "path"="/items/{id}/vocabulary",
 *                   "controller"=ItemVocabularyController::class,
 *                  }
 *     }
 * )
 * @ORM\Entity
 * @ORM\Table(name="`items`")
 */
class Item
{
    /**
     *
     * @ORM\Id
     * @ORM\Column(type="uuid", unique=true)
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank(message="Le nom du support ne peut-être vide.")
     * @Groups({"item.read", "item.write"})
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Groups({"item.read", "item.write"})
     */
    private $author;

    /**
     * @ORM\ManyToMany(targetEntity=Word::class)
     * @Groups({"item_words.read", "item_words.write"})
     * @ApiSubresource
     */
    private $words;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Groups({"item.read", "item.write"})
     */
    private $file;

    /**
     * @ORM\Column(type="integer", nullable=true, options={"default" : "0"}))
     * @Groups({"item.read"})
     */
    private $wordsNumber;


    /**
     * @var \DateTime
     *
     * @ORM\Column(type="datetime", options={"default":"2020-01-01 00:00:00"})
     * @Gedmo\Timestampable(on="create")
     * @Groups({"item.read"})
     */
    private $createdAt;

    /**
     * @var \DateTime
     *
     * @ORM\Column(type="datetime", options={"default":"2020-01-01 00:00:00"})
     * @Gedmo\Timestampable
     * @Groups({"item.read"})
     */
    private $updatedAt;


    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ----------------------------------------GETTER AND SETTER------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */


    public function __construct()
    {
        $this->words = new ArrayCollection();
        $this->id = Uuid::uuid4();
    }

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

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getAuthor(): ?string
    {
        return $this->author;
    }

    public function setAuthor(?string $author): self
    {
        $this->author = $author;

        return $this;
    }

    /**
     * @return Collection|Word[]
     */
    public function getWords(): Collection
    {
        return $this->words;
    }


    public function addWord(Word $word): self
    {
        if(!$this->words->contains($word))
        {
            $this->words[] = $word;
        }

        return $this;
    }

    public function removeWord(Word $word): self
    {
        $this->words->removeElement($word);

        return $this;
    }

    public function getFile(): ?string
    {
        return $this->file;
    }

    public function setFile(?string $file): self
    {
        $this->file = $file;

        return $this;
    }

    public function getWordsNumber(): ?int
    {
        return $this->wordsNumber;
    }

    public function setWordsNumber(?int $wordsNumber): self
    {
        $this->wordsNumber = $wordsNumber;

        return $this;
    }


    /**
     * @return \DateTime
     */
    public function getCreatedAt(): \DateTime
    {
        return $this->createdAt;
    }

    /**
     * @param \DateTime $createdAt
     * @return Quote
     */
    public function setCreatedAt(\DateTime $createdAt): Quote
    {
        $this->createdAt = $createdAt;
        return $this;
    }

    /**
     * @return \DateTime
     */
    public function getUpdatedAt(): \DateTime
    {
        return $this->updatedAt;
    }

    /**
     * @param \DateTime $updatedAt
     * @return Quote
     */
    public function setUpdatedAt(\DateTime $updatedAt): Quote
    {
        $this->updatedAt = $updatedAt;
        return $this;
    }


}

and Word

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\WordRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;
use Symfony\Component\Serializer\Annotation\Groups;


/**
 * @ORM\Entity
 * @ApiResource(attributes={"order"={"value": "ASC"}})
 * @ORM\Table(name="`words`")
 */
class Word
{
    /**
     *
     * @ORM\Id
     * @ORM\Column(type="uuid", unique=true)
     */
    private $id;

    /**
     * @Groups({"item_words.read"}),
     * @ORM\Column(type="string", length=255)
     */
    private $value;


    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ----------------------------------------GETTER AND SETTER------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------------------------------- */



    public function __construct()
    {
        $this->id = Uuid::uuid4();
    }

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

    public function getValue(): ?string
    {
        return $this->value;
    }

    public function setValue(string $value): self
    {
        $this->value = $value;

        return $this;
    }


}

Upvotes: 1

Views: 1932

Answers (1)

Loic H
Loic H

Reputation: 348

After digging for a while , to make it works the "method" must be present on the operation

He is the working annotation

/**
 * @ApiResource(
 *     normalizationContext={"groups"={"item.read"}},
 *     denormalizationContext={"groups"={"item.write"}},
 *     collectionOperations={"get", "post"},
 *     itemOperations={
 *          "get"={
 *              "method"="GET",
 *              "normalization_context"={"groups"={"item.read","item_words.read"}},
 *          },
 *          "put"={
 *              "method"="PUT",
 *              "normalization_context"={"groups"={"item.write", "item_words.write"}},
 *          },
 *         "delete",
 *         "getItemVocabulary"={
 *                   "method"="GET",
 *                   "path"="/items/{id}/vocabulary",
 *                   "controller"=ItemVocabularyController::class,
 *                  }
 *     }
 * )
 * @ORM\Entity
 * @ORM\Table(name="`items`")
 */

Upvotes: 1

Related Questions