question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Q: Return entity in a case if it already exist

See original GitHub issue

I have entity Tag, which have unique property tagValue. When I make a POST with already exists tagValue I want to get it in response.

config/validator/tag.yaml:

App\Entity\Tag:
  constraints:
    - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity: tagValue
  properties:
    tagValue:
      - NotBlank: ~

src/Entity/Tag.php:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use DateTimeInterface;
use DateTime;
use Exception;

/**
 * @ORM\Table(name="tag")
 * @ORM\Entity(repositoryClass="App\Repository\TagRepository")
 * @ORM\HasLifecycleCallbacks
 */
class Tag
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(type="integer")
     */
    private $id;

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

    // ...
}

When I make a POST:

curl --request POST \
  --url http://127.0.0.1:8888/api/tags \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --header 'x-auth-token: xxxxxxxxxxxxxxxx' \
  --data '{
	"tagValue": "test"
}'

I got response with just created entity and code 201. Everything is ok, but if I’ll make this request again, as expected, I’m getting response code 400 with response body:

{
  "type": "https:\/\/tools.ietf.org\/html\/rfc2616#section-10",
  "title": "An error occurred",
  "detail": "tagValue: This value is already used.",
  "violations": [
    {
      "propertyPath": "tagValue",
      "message": "This value is already used."
    }
  ]
}

But I want exist entity include to that response.

Any ideas how to do that without breaking REST rules?

(Symfony 4.2.5, api-platform/api-pack 1.2.0)

P.S. Same question on: https://stackoverflow.com/questions/57310654/return-entity-in-a-case-if-it-already-exist-api-platform

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
tylerwiegandcommented, Dec 18, 2020

I recently had this very same need but just making a query for the record in a data persister worked for me. Not sure if this is intended or not, but it feels a lot simpler than the current solution (which I did not want to mess with lol)

<?php

namespace App\DataPersister;

use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use App\Entity\Entity;
use App\Repository\EntityRepository;
use Doctrine\ORM\EntityManagerInterface;

class EntityPersister implements DataPersisterInterface
{
    /**
     * @var EntityManagerInterface
     */
    private $entityManager;

    /**
     * @var EntityRepository
     */
    private $entityRepository;

    /**
     * EntityPersister constructor.
     * @param EntityManagerInterface $entityManager
     * @param EntityRepository       $entityRepository
     */
    public function __construct(
        EntityManagerInterface $entityManager,
        EntityRepository $entityRepository
    ) {

        $this->entityManager    = $entityManager;
        $this->entityRepository = $entityRepository;
    }

    public function supports($data): bool
    {
        return $data instanceof Entity;
    }

    public function persist($data): Entity
    {
        $record = $this->entityRepository->findOneBy([
            'uniqueField' => $data->getUniqueField(),
        ]);

        if($record) {
            return $record;
        }

        $this->entityManager->persist($data);
        $this->entityManager->flush();

        return $data;
    }

    public function remove($data)
    {
        $this->entityManager->remove($data);
        $this->entityManager->flush();
    }
}
2reactions
soyukacommented, Sep 13, 2019

Might this be fixed by adding an entry in the documentation?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Return entity in a case if it already exist - API Platform
When I make a POST with already exists tagValue I want to get it in response. config/validator/tag.yaml : App\Entity\Tag: constraints: - Symfony ...
Read more >
Tracking vs. No-Tracking Queries - EF Core | Microsoft Learn
When the results are returned in a tracking query, EF Core will check if the entity is already in the context. If EF...
Read more >
QuerySet API reference | Django documentation
QuerySet API reference¶. This document describes the details of the QuerySet API. It builds on the material presented in the model and database...
Read more >
Doctrine Query Language - ORM
INSERT statements are not allowed in DQL, because entities and their relations have to be introduced into the persistence context through EntityManager#persist ...
Read more >
Structured binding declaration (since C++17)
Like a reference, a structured binding is an alias to an existing object. ... Case 1: if E is an array type, then...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found