到目前为止,我们一直在努力解决Symfony,Doctrine和Serializer的问题。
我希望能够只使用Symfony提供一个级别深度的JSON REST API,这样我就可以管理我的"外键"和直接来自视图的关系逻辑。
GET /people/1
{
id:1,
name:"theonewhoknocks",
friends: [3, 12, 25]
}
使用FosRESTBundle,我们一直在努力争取成功。 (我们已经看过"深度" anotations和"群组"模型的观点,但这些都不符合我们的需要。)
问题很简单,在我们为未来的API做出选择之前,我们必须知道:
api-platform是否能够提供简单的一个级别(带有明显的外键)REST API?
答案 0 :(得分:2)
API平台可以使用Serializer Symfony bundle及其注释集来处理该问题。
要定义操作将返回的内容,我们使用normalizationContext
,它定义属性组以包含在api操作的结果中。然后,要包含的属性具有该组名链接到@Groups
序列化程序注释
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity
* @ApiResource(normalizationContext={"groups"={"read"}}
*/
class Book {
/**
* @ORM\Column
* @Groups({"read"})
*/
private $title;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="books")
* @Groups({"read"})
*/
private $author;
/**
* Will not be included in result
*/
private $secret_comment;
}
如果此处的关系列位于$author
组中,则在子类的组中定义的属性将包括在结果中
/**
* @ORM\Entity
* @ApiResource(normalizationContext={"groups"={"read"}}
*/
class User {
/**
* @ORM\Column
* @Groups({"read"})
*/
private $username;
}
为了避免循环递归,您可以指定带有注释@MaxDepth(n)
的子关系连接的最大深度,其中n是最大深度(在您的情况下为1)。必须在enable_max_depth
批注的序列化程序上下文中使用@ApiResource
属性启用此批注
/**
* @ApiPlatform(normalizationContext={"groups"={"read"}, "enable_max_depth"=true}
*/
class Book {
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="books")
* @Groups({"read"})
* @MaxDepth(1)
*/
private $author;
}
请注意,在这种情况下,API平台是现有包和功能的集合。请参阅主要捆绑包以获取详细信息(此处为Symfony Serializer捆绑包)
答案 1 :(得分:1)
是的,使用API平台很容易做到这一点。看一下the Getting Started guide,它介绍了如何在几分钟内创建这样的API。
答案 2 :(得分:0)
请注意,symfony序列化器上的MaxDepth
可能无法正常工作,请参阅https://github.com/symfony/symfony/issues/33466
注释基本上说“从这里开始,将N个相同的CLASS实例渲染到图中”
所以给定了伪结构,如
Class A:
@MaxDepth(1)
Class B:
Class C:
Class D:
将渲染整个A.B.C.D
,而
Class A:
@MaxDepth(1)
Class B:
Class B:
Class B:
只会渲染A.B.B
与例如JMS序列化程序正在执行操作,其中MaxDepth
的真正含义是“从此开始,最多N个步入关系图中”。
最糟糕的是api平台不支持JMS序列化程序:https://github.com/api-platform/api-platform/issues/753
因此,对您的问题atm的答案是:不。 :/