-
-
Notifications
You must be signed in to change notification settings - Fork 924
Closed
Description
API Platform version(s) affected: 2.6
Description
I've defined a write group for my category entity which is completely ignored on POST requests. The problem persist on the documentation (openapi) page. The fields that have only read groups are being present on the POST request but the values are ignored upon send.
How to reproduce
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\CategoriesRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(
* normalizationContext={"groups"={"category: read"}},
* denormalizationContext={"groups"={"category: write"}},
* attributes={}
* )
* @ORM\Entity(repositoryClass=CategoriesRepository::class)
* @ORM\Table("`categories`")
* @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=true, hardDelete=true)
*/
class Category
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"category: read", "category: write"})
*/
private int $id;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"category: read", "category: write"})
*/
private string $title;
/**
* @ORM\Column(type="text", nullable=true)
* @Groups({"category: read", "category: write"})
*/
private ?string $description;
/**
* @ORM\Column(type="boolean")
* @Groups({"category: read", "category: write"})
*/
private bool $isPublic = true;
/**
* @ORM\Column(name="deleted_at", type="datetime", nullable=true)
* @Groups({"category: read"})
*/
private ?\DateTimeInterface $deletedAt;
/**
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime")
* @Groups({"category: read"})
*/
private ?\DateTimeInterface $updatedAt;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
* @Groups({"category: read"})
*/
private ?\DateTimeInterface $createdAt;
/**
* @ORM\ManyToMany(targetEntity=Product::class, mappedBy="categories")
* @Groups({"category: read", "category: write"})
*/
private $products;
public function __construct()
{
$this->products = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getIsPublic(): ?bool
{
return $this->isPublic;
}
public function setIsPublic(bool $isPublic): self
{
$this->isPublic = $isPublic;
return $this;
}
public function getDeletedAt(): ?\DateTimeInterface
{
return $this->deletedAt;
}
public function setDeletedAt(?\DateTimeInterface $deletedAt): self
{
$this->deletedAt = $deletedAt;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return Collection|Product[]
*/
public function getProducts(): Collection
{
return $this->products;
}
public function addProduct(Product $product): self
{
if (!$this->products->contains($product)) {
$this->products[] = $product;
$product->addCategory($this);
}
return $this;
}
public function removeProduct(Product $product): self
{
if ($this->products->removeElement($product)) {
$product->removeCategory($this);
}
return $this;
}
}
Additional Context
{
"title": "string",
"description": "string",
"deletedAt": "2021-04-26T19:47:27.683Z",
"updatedAt": "2021-04-26T19:47:27.683Z",
"createdAt": "2021-04-26T19:47:27.683Z",
"products": [
"string"
]
}
The above is the example body from the POST request, which should not have the deletedAt, updatedAt, createdAt fields that are in the read group only. If i'm changing the value of any of those three, it will be ignored and the default value will be used ( in this case the current datetime)
TimGels
Activity
guilliamxavier commentedon Apr 27, 2021
That's the first time I see spaces in group names, could this be related? 🤔 Does the problem persist after renaming them to spaceless
"category:read"
/"category:write"
(and clearing the cache)?lebadapetru commentedon Apr 28, 2021
@guilliamxavier , i removed the spaces yet the problem persist
If i change the
category:read
tocategory:write
on theprivate ?\DateTimeInterface $deletedAt;
prop, it disappear from the POST request body, but also from the GET response ( this one is right ).guilliamxavier commentedon Apr 28, 2021
Weird indeed... (BTW I also just noticed you have the write group on id although no setter)
Another random thought: could there be an interaction with the
@Gedmo
annotations? 😕lebadapetru commentedon Apr 28, 2021
Yeah, no reason behind that, it just slipped in. I thought about Gedmo too, but i removed it and the problem is still there...
Can it be a bug on the newest version? Is anyone else experiencing this?
lebadapetru commentedon Apr 28, 2021
Here's the apiplatform config, just in case:
soulcodex commentedon Apr 29, 2021
I have the same trouble on POST endpoints the request body have a weird behavior for POST and PUT endpoints definitions using YAML or Annotations 😭
Looks like the OpenApiFactory cant read the groups from Symfony Serializer
nickvanderzwet commentedon May 25, 2021
Maybe related, I'm not sure: #3668
The Read/Write models are already made for the foreign object (in your case product) and skipped for the actual entity..
It seems like it only affects the api config, responses seems to be okay.
alanpoulain commentedon Jun 23, 2021
Probably solved by 2.6.5.
stale commentedon Nov 5, 2022
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
stale commentedon Jan 4, 2023
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.