JMS Serializer:如何在不在任何地方添加注释的情况下传播属性的组排除?
JMS Serializer: how to propagate group exclusion for properties without adding annotations everywhere?
我正在使用 Symfony 和 JMS 序列化程序(通过 FOSRestundle)构建一个 API 来公开树。我创建了一个 Tree 实体,其中包含一个 id、一个标题和树的根节点。我也创建了一个节点实体,包含节点之间的链接。
我的 API 包含一个 public 部分和一个管理部分,我希望根据控制器属于一个或另一个来以不同方式公开树:
- 在 public api 中,我希望我的树的 ID 和标题只可见
- 在管理 api 中,我希望树的所有属性都可见,包括根节点。
我得到了以下代码:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
/**
* @ORM\Entity(repositoryClass="App\Repository\TreeRepository")
*/
class Tree {
/**
* Unique ID to identify the tree
*
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Serializer\Groups({"ADMIN", "API"})
*/
private $id;
/**
* Name of the tree (example = a failure to diagnose)
*
* @ORM\Column(type="string", length=255)
* @Serializer\Groups({"ADMIN", "API"})
*/
private $title;
/**
* @ORM\OneToOne(targetEntity="App\Entity\Node")
* @ORM\JoinColumn(referencedColumnName="id")
*
* @Serializer\Groups({"ADMIN"})
*/
private $firstNode;
public function getId()
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getFirstNode(): ?Node
{
return $this->firstNode;
}
public function setFirstNode(?Node $firstNode): self
{
$this->firstNode = $firstNode;
return $this;
}
}
如您所见,我创建了两个排除组,以便我可以隐藏或公开我想要的属性。太棒了!
但是为了使节点内的属性可见,我必须为所有属性添加@Serializer\Groups
注释,并传播它到属性的 classes 一直沿着依赖项 .
我不想在我的所有实体 class 中复制 @Serializer\Groups
注释。所以我尝试使用 JMS 排除策略 (@Serializer\ExclusionPolicy()
),但这似乎不起作用。
有没有办法 expose/exclude 一个 class, inconditionnaly 当前的 JMS 排除组?
谢谢
24 小时后,我意识到我误用了 jms 序列化程序的排除组概念。
- 之前:我有 2 个组:"API" 和 "ADMIN"。有了这个组织,我需要在组中声明每个 属性,并且沿着我的依赖树(就像白名单)声明这个。
- 现在:我只有一组"ADMIN"。对于这个组织,我需要:
- 在群组 "ADMIN" 中声明,仅 public 不可见的属性
- 为 "Default" 组的 public 请求声明我的控制器,并为仅管理员请求的 "ADMIN" 和 "Defaults" 组声明我的控制器。我不需要在依赖树中传播任何排除组。
这很好地解决了我的问题。但也许我最初的需求仍然是合法的。
我正在使用 Symfony 和 JMS 序列化程序(通过 FOSRestundle)构建一个 API 来公开树。我创建了一个 Tree 实体,其中包含一个 id、一个标题和树的根节点。我也创建了一个节点实体,包含节点之间的链接。
我的 API 包含一个 public 部分和一个管理部分,我希望根据控制器属于一个或另一个来以不同方式公开树:
- 在 public api 中,我希望我的树的 ID 和标题只可见
- 在管理 api 中,我希望树的所有属性都可见,包括根节点。
我得到了以下代码:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
/**
* @ORM\Entity(repositoryClass="App\Repository\TreeRepository")
*/
class Tree {
/**
* Unique ID to identify the tree
*
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Serializer\Groups({"ADMIN", "API"})
*/
private $id;
/**
* Name of the tree (example = a failure to diagnose)
*
* @ORM\Column(type="string", length=255)
* @Serializer\Groups({"ADMIN", "API"})
*/
private $title;
/**
* @ORM\OneToOne(targetEntity="App\Entity\Node")
* @ORM\JoinColumn(referencedColumnName="id")
*
* @Serializer\Groups({"ADMIN"})
*/
private $firstNode;
public function getId()
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getFirstNode(): ?Node
{
return $this->firstNode;
}
public function setFirstNode(?Node $firstNode): self
{
$this->firstNode = $firstNode;
return $this;
}
}
如您所见,我创建了两个排除组,以便我可以隐藏或公开我想要的属性。太棒了!
但是为了使节点内的属性可见,我必须为所有属性添加@Serializer\Groups
注释,并传播它到属性的 classes 一直沿着依赖项 .
我不想在我的所有实体 class 中复制 @Serializer\Groups
注释。所以我尝试使用 JMS 排除策略 (@Serializer\ExclusionPolicy()
),但这似乎不起作用。
有没有办法 expose/exclude 一个 class, inconditionnaly 当前的 JMS 排除组? 谢谢
24 小时后,我意识到我误用了 jms 序列化程序的排除组概念。
- 之前:我有 2 个组:"API" 和 "ADMIN"。有了这个组织,我需要在组中声明每个 属性,并且沿着我的依赖树(就像白名单)声明这个。
- 现在:我只有一组"ADMIN"。对于这个组织,我需要:
- 在群组 "ADMIN" 中声明,仅 public 不可见的属性
- 为 "Default" 组的 public 请求声明我的控制器,并为仅管理员请求的 "ADMIN" 和 "Defaults" 组声明我的控制器。我不需要在依赖树中传播任何排除组。
这很好地解决了我的问题。但也许我最初的需求仍然是合法的。