The menu on a scroll

Exercise 1 of 6 in chapter 5 · 200 XP · 5 objectives checked by tests

Topics covered: JSON API$this->json()Serializer#[Groups]

The Adventurers' Guild has just equipped its members with magic scrolls: they can browse the taverns of the region on them, book a table… Gorm wants the Drunken Dragon to be listed. The trouble is, scrolls can't read HTML: they speak JSON.

First step: publish the menu.

Your mission

In Api\CarteController::plats() (GET /api/dishes), return the menu as JSON, from cheapest to most expensive:

[
    {
        "slug": "wayfarer-bread",
        "nom": "Wayfarer Bread",
        "description": "One bite keeps you walking all day…",
        "prix": 2.5,
        "specialite": false,
        "categorie": { "nom": "Sides" }
    }
]

The JSON keys are the entities' property names, so they stay French: nom (name), prix (price), specialite (specialty), categorie (category).

To try your responses, use the Requests tab, next to the preview. Its buttons prepare ready-made requests.

Try the naive version first

$this->json($platRepository->findParPrixCroissant()) (findParPrixCroissant = find by increasing price), and watch what happens. The Serializer turns objects into arrays by reading all their getters. So it also follows the relations: getCategorie(), then the category's getPlats(), then those dishes… There is also getCreateur() (the creator), which would publish Bruna's email and her password hash!

The right way: groups

Decide explicitly what is public. Mark each property to publish with #[Groups(['carte'])] (carte = menu), then ask the Serializer for that group:

return $this->json($donnees, context: ['groups' => ['carte']]);

A property without a group is no longer published. That's the right habit for an API: anything that isn't explicitly public stays private.