Skip to content
Advertisement

Symfony 5 API populate related object entities

I am trying to create a simple web app using Symfony 5. I am using the API.

Currently when calling some endpoint it only displays the IRI link to the related link:

I need instead to display the related entity object itself; if I get the Item endpoint the related entity Program should be returned this:

{
    "id": 1,
    "program": {
        "id": 1,
        "name": "First program"
    },
    "description": "fgdfg",
    "comment": "dfgdfg"
{

So, this is how the table looks:

I thought setting up a subresource would be enough to get the object but it wasn’t:

  1. In the InventoryItem entity configured @ApiSubresource annotation of the Program property:

    /**
     * @ORMManyToOne(targetEntity=Program::class, inversedBy="inventoryItems")
     * @ORMJoinColumn(nullable=false)
     * @ApiSubresource
     */
    private $program;
    
  2. In resources.yaml file I configured the subresource:

    AppEntityInventoryItem:
       properties:
           program:
               subresource:
                   resourceClass: 'AppEntityProgram'
                   collection: true
    

This still returns the IRI instead of the object, The only thing that has changed was that now I can access to the related entity for the current object in this URL: http://localhost:8000/api/inventory_items/1/program.json.

Any idea on how to return the related entity object itself instead of the IRI URL?

Advertisement

Answer

You’re searching to serialize your item. So I guess this is more a serialization problem than a sub-resource problem. I think you should use serialization group instead of SubResource.

SOLUTION1 Serialize the embedding relation

The “Embedding relation” provides an example with Book and Author.

<?php
// api/src/Entity/Item.php

namespace AppEntity;

use ApiPlatformCoreAnnotationApiResource;
use SymfonyComponentSerializerAnnotationGroups;

/**
 * @ApiResource(normalizationContext={"groups"={"item"}})
 */
class Item
{
    /**
     * @Groups({"item"})
     */
    public $description;

    /**
     * @Groups({"item"})
     */
    public $comment;

    /**
     * @Groups({"item"})
     */
    public $program;

    // ...
}

// api/src/Entity/Person.php

namespace AppEntity;

use ApiPlatformCoreAnnotationApiResource;
use SymfonyComponentSerializerAnnotationGroups;

/**
 * @ApiResource
 */
class Person
{
    /**
     * ...
     * @Groups("item") <=== This is item, not program but you can have two groups
     */
    public $name;

    // ...
}

SOLUTION2 Mix subresources and serialization groups

This example should work, but (if subresources are necessary) you can mixed subresources and serializations too, but in you case I guess that the first solution is the best.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement