xavier
xavier

Reputation: 11

How to display extra fields from a ManyToMany relation table when requesting a sub resource

I need to display the "skill" of the "drivers" of specific "cars", which comes from a relational table "Relation_Car_Driver", this field should only appear for sub-resources calls "/cars/:id/drivers" and "/drivers/:id/cars"

I have 3 Tables :

My main API resources are :

My API sub resources are :

For those sub-resources calls i want to return the "skill" value coming from their relation !

Entity Car :

# src/Entity/Car.php
namespace App\Entity;

/**
 * @ORM\Table(name="Car")
 * @ORM\Entity
 *
 * @ApiResource(
 *     subresourceOperations={
 *          "drivers_get_subresource"={
 *              "method"="GET",
 *              "path"="/cars/{id}/drivers"
 *          }
 *      }
 * )
 */
class Car
{
// ...
    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Driver", inversedBy="cars")
     * @JoinTable(name="Relation_Car_Driver",
     *      joinColumns={@JoinColumn(name="car_id", referencedColumnName="id")},
     *     inverseJoinColumns={@JoinColumn(name="driver_id", referencedColumnName="id")}
     * )
     * @ApiSubresource(maxDepth=1)
     */
    private $drivers;
}

Entity Driver :

# src/Entity/Driver.php
namespace App\Entity;

/**
 * @ORM\Table(name="Driver")
 * @ORM\Entity
 *
 * @ApiResource(
 *     subresourceOperations={
 *          "cars_get_subresource"={
 *              "method"="GET",
 *              "path"="/drivers/{id}/cars"
 *          }
 *      }
 * )
 */
class Driver
{
// ...
    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Car", inversedBy="drivers")
     * @JoinTable(name="Relation_Car_Driver",
     *      joinColumns={@JoinColumn(name="driver_id", referencedColumnName="id")},
     *     inverseJoinColumns={@JoinColumn(name="car_id", referencedColumnName="id")}
     * )
     * @ApiSubresource(maxDepth=1)
     */
    private $cars;
}

Entity Relation_Car_Driver :

<?php

namespace App\Entity;


/**
 * RelationCarDriver
 *
 * @ORM\Table(name="Relation_Car_Driver")
 * @ORM\Entity
 */
class RelationCarDriver
{
// ..
    /**
     * @var int|null
     *
     * @ORM\Column(name="skill", type="int", nullable=true)
     */
    private $skill;
}

Actual result from GET /drivers/:id/cars:

{
  "@context": "/api/contexts/Car",
  "@id": "/api/drivers/1/cars",
  "@type": "hydra:Collection",
  "hydra:member": [
    {
      "@id": "/api/cars/1",
      "@type": "Car",
      "id": 1,
      "model": "Mustang"
    },
    {
      "@id": "/api/cars/2",
      "@type": "Car",
      "id": 2,
      "model": "Chevrolet"
    }
  ],
  "hydra:totalItems": 2
}

Expected result from GET /drivers/:id/cars:

{
  "@context": "/api/contexts/Car",
  "@id": "/api/drivers/1/cars",
  "@type": "hydra:Collection",
  "hydra:member": [
    {
      "@id": "/api/cars/1",
      "@type": "Car",
      "id": 1,
      "model": "Mustang",
      "skill": 63
    },
    {
      "@id": "/api/cars/2",
      "@type": "Car",
      "id": 2,
      "model": "Chevrolet",
      "skill": 13
    }
  ],
  "hydra:totalItems": 2
}

I have no clue how to achieve that ? Thanks

Upvotes: 1

Views: 548

Answers (1)

Zenel Shabani
Zenel Shabani

Reputation: 301

I had a similar issue and just found your post. I managed to solve this using a group (eg: api_read) defined on the "Driver" entity, and adding that group to the "skill" property wil print it flattend out with "car" entity, thus achieving what u were looking for

Upvotes: 0

Related Questions