So far we've been struggling with Symfony, Doctrine, and Serializer depth.
I'd like to be able to provide just one-level-depth JSON REST API with Symfony, allowing me to manage my "foreign key" and relation logic directly from the view.
GET /people/1
{
id:1,
name:"theonewhoknocks",
friends: [3, 12, 25]
}
Using FosRESTBundle, we've been strugling at succeeding on that. (we've seen "depth" anotations and "groups" views for models, but none of this fit our need).
The question is simple, before we make a choice for our future API, we have to know:
is api-platform able to provide a dead simple one level (with apparent foreign keys) REST API ?
API Platform can handle that using the Serializer Symfony bundle and its annotation set.
To define what will be returned by an operation we use a normalizationContext
which define group(s) of property to include in result of an api operation. Property to include have then this group name linked to @Groups
serializer annotation
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;
}
If a relation column is in a Group as $author
here, properties defined in a group in the child class will be included in the result
/**
* @ORM\Entity()
* @ApiResource(normalizationContext={"groups"={"read"}})
*/
class User {
/**
* @ORM\Column()
* @Groups({"read"})
*/
private $username;
}
In order to avoid cyclic recursion you can specify the max depth of child relation joins with annotation @MaxDepth(n)
where n is the max depth (1 in your case). This annotation has to be enabled with enable_max_depth
property in serializer context of the @ApiResource
annotation
/**
* @ApiPlatform(normalizationContext={"groups"={"read"}, "enable_max_depth"=true})
*/
class Book {
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="books")
* @Groups({"read"})
* @MaxDepth(1)
*/
private $author;
}
Please note that API Platform is in this case an agregation of existing bundles and features. Refer to the main bundles for detailed informations (here the Symfony Serializer bundle)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With