I have Users and Message Entity, which has relation of OneToMany. Currently API response looks something like this:
{
"data": {
"messages": [
{
"id": "1ed01e01-3e73-6b62-bdcb-3de4f998be6c",
"toUser": {
"id": "1ed01e01-1133-690e-8ac8-6b6e91ccf39b",
"__initializer__": [],
"__cloner__": [],
"__isInitialized__": false
},
"fromUser": {
"id": "1ed01e01-1133-671a-8d31-6b6e91ccf39b",
"__initializer__": [],
"__cloner__": [],
"__isInitialized__": false
},
"createdAt": "2022-07-12T15:42:23 03:00",
"content": "Content."
}
],
"count": 1
}
}
I would like toUser
and fromUser
only display their id without rest of fields from Message Entity, like so:
"toUser": "1ed01e01-1133-690e-8ac8-6b6e91ccf39b",
"fromUser": "1ed01e01-1133-671a-8d31-6b6e91ccf39b"
Here is how my entities and serialization looks like. User.php
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: '`user`')]
class User
{
#[ORM\Id]
#[ORM\Column(type: 'uuid', unique: true)]
#[ORM\GeneratedValue(strategy: "CUSTOM")]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private $id;
#[ORM\Column(type: 'string', length: 255, unique: true)]
private $username;
#[ORM\OneToMany(mappedBy: 'toUser', targetEntity: Message::class, orphanRemoval: true)]
private $messages;
...
}
Messages.php
#[ORM\Entity(repositoryClass: MessageRepository::class)]
class Message
{
#[ORM\Id]
#[ORM\Column(type: 'uuid', unique: true)]
#[ORM\GeneratedValue(strategy: "CUSTOM")]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private $id;
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'messages')]
#[ORM\JoinColumn(nullable: false)]
private $toUser;
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'messages')]
#[ORM\JoinColumn(nullable: false)]
private $fromUser;
#[ORM\Column(type: 'datetime_immutable')]
private $createdAt;
#[ORM\Column(type: 'datetime', nullable: true)]
private $updatedAt;
#[ORM\Column(type: 'text')]
private $content;
public function getId(): ?UuidV6
{
return $this->id;
}
}
MessageController.php
public function getAllMessages() {
$serialized = $serializer->serialize($messages, 'json', [
ObjectNormalizer::SKIP_NULL_VALUES => true,
ObjectNormalizer::IGNORED_ATTRIBUTES => ['username', 'messages', 'created_at'],
ObjectNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object) {
return $object->getId();
},
]);
$dataMessage = json_decode($serialized);
$json = json_encode([
"data" => array("recipients" => $dataMessage, "count" => count($dataMessage))
]);
}
CodePudding user response:
I think the best would be to create a models class to formalize your data. At least you are sure that you manage your object 100% and it does not show you any useless attribute
class MessageModel
{
public int $id;
public string $toUser;
public string $fromUser;
public string $createdAt;
public string $content;
/**
* @param Message $message
*/
public function __construct(Message $message)
{
$this->id = $message->getId();
$this->toUser = $message->getUser()->getId()
$this->fromUser = $message->getUser()->getId()
$this->createdAt = $message->getCreatedAt()->format('d/m/Y H:i:s');
$this->updatedAt = $message->getUpdatedAt() === null ? '' : $message->getUpdatedAt()->format('d/m/Y H:i:s');
$this->content = $message->getContent();
}
/**
* @return $this
*/
public function build(): MessageModel
{
return $this;
}
}
for the code I let you adapt it I have not tested