'ApiPlatform Annotations normalizationContext not working as expected

I´m trying to add a route for my Report-entity and define a custom controller for it. The controller seems to work as breakpoints in it are working. Unfortunately, the normalization_context groups do not work at all. I´m trying to have a group for the normal 'get' and the 'generic'. When i make a GET-call to /api/reports/, i get a response with the correct data

{    
  "@id": "/api/reports/16e9e2d1-faf1-4fed-92e2-dd855f9f6848",  
  "@type": "Report",  
  "year": "2022-01-19T00:00:00+01:00"
  "settings": {  
    "@id": "/api/settings/cf062dba-1150-4881-87d8-b510e57e499f",
    "@type": "Settings",
    "baseYear": "2022-01-19T00:00:00+01:00",
    "location": "/api/locations/5f0a3011-87da-4c23-8c43-e9f749856fcf"
  },
}

A call to the api/reports/generic on the other hand does not work as expected.

Expected Result:

{    
  "company": "11112222-11aa-4442-8791-dd87e9abb7c2" 
  "year": "2022-01-19T00:00:00+01:00"
  "settings": {  
    "baseYear": "2022-01-19T00:00:00+01:00",
    "location": "/api/locations/5f0a3011-87da-4c23-8c43-e9f749856fcf"
  },
}

Current Result:

{    
  "year": "2022-01-19T00:00:00+01:00",
  "settings": {},
}

Report.php

<?php

namespace App\Entity;

/**
 * @ApiResource(
 *     normalizationContext={"groups"={"rep_read"}},
 *     denormalizationContext={"groups"={"report:write"}},
 *     collectionOperations={
 *          "get",
 *          "generic"={
 *                   "method"="GET",
 *                   "path"="/reports/generic",
 *                   "normalization_context"={"groups"={"rep_read", "generic"}},
 *                   "openapi_context"={
 *                       "summary"="Get a generic report for a company. if none exists, create one"
 *                   },
 *                   "controller"="App\Controller\RouteController::getCompanyReport",
 *          }
 *     }
 * )
 */
class Report
{
    /**
     * @ORM\Column(type="uuid")
     * @Groups({"generic"})
     */
    private $company;

    /**
     * @ORM\Column(type="date")
     * @Groups({"rep_read", "generic"})
     */
    private $year;

    /**
     * @ORM\ManyToOne(targetEntity=Settings::class)
     * @ORM\JoinColumn(nullable=false)
     * @Groups({"rep_read"})
     */
    private $settings;

}

RouteController.php

<?php

namespace App\Controller;

class RouteController extends AbstractController
{

    public function getCompanyReport(Request $request): Response
    {
        $report = $this->repositories['report']->findOneBy(['company' => $company]);
        
        $debug = $request->attributes->get('_api_normalization_context')['groups']; 
        // --> [0 = "rep_read", 1 = "generic"]
        return $this->json([
                'report' => $report
        ], Response::HTTP_OK);
    }
}

My temporary $debug variable shows me it technically knows the context_groups. But for some reason, it does not get included in the response. What an I doing wrong with the groups/normalizationContext?



Solution 1:[1]

Your nested generic normalization_context (!) is snake case. It should be camel case.

/**
 * @ApiResource(
 *     normalizationContext={"groups"={"rep_read"}},
 *     denormalizationContext={"groups"={"report:write"}},
 *     collectionOperations={
 *          "get",
 *          "generic"={
 *                   "method"="GET",
 *                   "path"="/reports/generic",
 *          ---->>>  "normalization_context"={"groups"={"rep_read", "generic"}},
 *                   "openapi_context"={
 *                       "summary"="Get a generic report for a company. if none exists, create one"
 *                   },
 *                   "controller"="App\Controller\RouteController::getCompanyReport",
 *          }
 *     }
 * )
 */

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 btl-sw