I'm trying to integrate FOSRestBundle with BazingaHateoasBundle but the links (that I expected to be automatically generated) are still missing from the response. What is wrong with my set-up?
Here are my configs:
composer.json [excerpt]:
"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
And here are my classes:
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;
}
}
Testing:
GET http://localhost:8000/api/groups response:
[
{
"name": "person1",
"slug": "person1"
},
{
"name": "person2",
"slug": "person2"
}
]
Expected:
[
{
"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" }
}
}
]
Researched:
https://github.com/willdurand/BazingaHateoasBundle/blob/master/Resources/doc/index.md#serializing-objects - doesn't show integration with the FOS bundle. It just constructs the Response manually.
https://github.com/willdurand/Hateoas/issues/238 - suggested removing serializedGroups, but I need groups to properly hide/expose fields to be displayed
Symfony and Wildurand/Hateoas Bundle - no links on JSON reposnse - the OP just manually constructed the response object, thus did not actually use the features of FOSRestBundle
https://symfony.com/doc/master/bundles/FOSRestBundle/1-setting_up_the_bundle.html#b-enable-a-serializer - Because the JMSSerializerBundle is the only serializer that I installed, I assume that it is the one used by the FOSRestBundle to automatically serialize the data. Thus I should not manually serialize the data and construct the response, contrary to the solutions I found.