我正在尝试将FOSRestBundle与BazingaHateoasBundle集成在一起,但是响应中仍然缺少链接(我希望会自动生成)。我的设置有什么问题?
这是我的配置:
composer.json [摘录]:
"require": {
"php": "^7.1.3",
"friendsofsymfony/rest-bundle": "^2.5",
"jms/serializer-bundle": "^2.4",
"lexik/jwt-authentication-bundle": "^2.6",
"sensio/framework-extra-bundle": "^5.2",
"stof/doctrine-extensions-bundle": "^1.3",
"symfony/flex": "^1.1",
"symfony/framework-bundle": "4.2.*",
"willdurand/hateoas-bundle": "^1.4"
},
jms_serializer.yaml:
jms_serializer:
visitors:
xml:
format_output: '%kernel.debug%'
fos_rest.yaml:
fos_rest:
zone:
- { path: ^/api/* }
view:
view_response_listener: true
format_listener:
rules:
- { path: ^/api, prefer_extension: true, fallback_format: json, priorities: [ json ] }
routing_loader:
default_format: json
body_listener:
array_normalizer: fos_rest.normalizer.camel_keys
serializer:
serialize_null: true
body_converter:
enabled: true
validate: true
这是我的课程:
PersonsController.php:
/**
* @Rest\Route("/persons")
*/
class PersonsController extends AbstractFOSRestController
{
/**
* @Rest\Get("")
* @return View
*/
public function getList()
{
$repository = $this->getDoctrine()->getRepository(Person::class);
$view = $this->view(
$repository->findAll()
);
$view->getContext()->setGroups(['default']);
return $view;
}
}
Person.php
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Hateoas\Configuration\Annotation as Hateoas;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity(repositoryClass="App\Repository\PersonRepository")
* @UniqueEntity("slug")
* @Serializer\ExclusionPolicy("all")
* @Hateoas\Relation("self", href = "expr('/api/persons/' ~ object.getSlug())")
*/
class Person
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Serializer\Expose
* @Serializer\Groups({"default"})
*/
private $name;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Gedmo\Slug(fields={"name"})
* @Serializer\Expose
* @Serializer\Groups({"default"})
* @Serializer\XmlAttribute
*/
private $slug;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getSlug()
{
return $this->slug;
}
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
}
测试:
获取http://localhost:8000/api/groups响应:
[
{
"name": "person1",
"slug": "person1"
},
{
"name": "person2",
"slug": "person2"
}
]
预期:
[
{
"name": "person1",
"slug": "person1",
"_links": {
"self": { "href": "http://example.com/api/persons/person1" }
}
},
{
"name": "person2",
"slug": "person2",
"_links": {
"self": { "href": "http://example.com/api/persons/person2" }
}
}
]
已研究:
https://github.com/willdurand/BazingaHateoasBundle/blob/master/Resources/doc/index.md#serializing-objects-未显示与FOS软件包的集成。它只是手动构造响应。
https://github.com/willdurand/Hateoas/issues/238-建议删除serializedGroups,但我需要使用组才能正确隐藏/公开要显示的字段
Symfony and Wildurand/Hateoas Bundle - no links on JSON reposnse-OP只是手动构造了响应对象,因此实际上并未使用FOSRestBundle的功能
https://symfony.com/doc/master/bundles/FOSRestBundle/1-setting_up_the_bundle.html#b-enable-a-serializer-因为JMSSerializerBundle是我安装的唯一序列化程序,所以我假设它是FOSRestBundle用来自动序列化数据的序列化程序。因此,与我找到的解决方案相反,我不应该手动序列化数据并构造响应。
答案 0 :(得分:0)
我只需要在 Relation 批注中添加 exclusion 属性,并指定应在其中显示的组。
/**
* @ORM\Entity(repositoryClass="App\Repository\PersonRepository")
* @UniqueEntity("slug")
* @Serializer\ExclusionPolicy("all")
* @Hateoas\Relation(
* "self",
* href = "expr('/api/persons/' ~ object.getSlug())",
* exclusion = @Hateoas\Exclusion(groups={"default"})
* )
*/
class Person
{ ...