dayan
dayan

Reputation: 402

Exclude entity property from API Platform collection operation

I'm exploring the Symfony API Platform. I want to hide some properties of entity product when getting list of products. I've creed a test normalizer, but my code keep ignoring me. Normalizer is not being called, all data goes directly into output. Please help.

products.php

namespace App\Entity;

 /**
 * @ORM\Table(schema="new_api", name="products")
 * @ORM\Entity(repositoryClass="App\Repository\ProductsRepository")
 * @UniqueEntity("productName", message="The product name must be unique")
 * @ApiResource(
 *     normalizationContext={"groups"={"get-product", "get-products"}},
 *     denormalizationContext={"groups"={"user", "user:write"}},
 *     collectionOperations={
 *         "get"={"security"="is_granted('ROLE_PRODUCTS')", },
 *         "post"={"security"="is_granted('ROLE_PRODUCTS_ADD')"}
 *     },
 *     itemOperations={
 *         "get"={"security"="is_granted('ROLE_PRODUCTS')"},
 *         "put"={"security"="is_granted('ROLE_PRODUCTS_EDIT')"},
 *         "patch"={"security"="is_granted('ROLE_PRODUCTS_EDIT')"},
 *         "delete"={"security"="is_granted('ROLE_PRODUCTS_EDIT')"},
 *     },
 * )
 */

class Products
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue
     * @Groups({"get-product", "get-products"})
     */
    private $id;

    /**
     * @Groups({"get-product", "get-products"})
     * @SerializedName("name")
     * @ORM\Column(name="product_name", type="string", length=255, unique=true)
     * @Assert\NotBlank(message="The product name cannot be empty")
     */
    private $productName;

    /**
     * @Groups({"get-product"})
     * @ORM\Column(name="description", type="text", length=65535, nullable=false)
     */
    private $description;

}


services.yaml

    'App\Serializer\ProductsNormalizer':
            arguments: [ '@api_platform.serializer.normalizer.item' ]
            tags: [ 'serializer.normalizer' ]
            autoconfigure: false

Upvotes: 1

Views: 3290

Answers (1)

yivi
yivi

Reputation: 47308

Using a normalizer is not necessary.

You've already defined the serialization groups for the properties (get-product and get-products,).

Now you just need to declare them in use for each operation. Or define a default normalization context for the resource, and just override it for the operation that should use a different serialization group.

For example:

/**
 * @ApiResource(
 *     normalizationContext={"groups"={"get-product"}},
 *     denormalizationContext={"groups"={"user", "user:write"}},
 *     collectionOperations={
 *         "get"={
 *               "security"="is_granted('ROLE_PRODUCTS')",
 *               "normalization_context"={"groups"={"get-products"}}
 *         },
 *         "post"={"security"="is_granted('ROLE_PRODUCTS_ADD')"}
 *     },
 *     itemOperations={
 *         "get"={"security"="is_granted('ROLE_PRODUCTS')"},
 *         "put"={"security"="is_granted('ROLE_PRODUCTS_EDIT')"},
 *         "patch"={"security"="is_granted('ROLE_PRODUCTS_EDIT')"},
 *         "delete"={"security"="is_granted('ROLE_PRODUCTS_EDIT')"},
 *     },
 * )
 */

With the above, you will by default use the get-product serialization group for responses, with the exception of the collection GET operation, that uses the get-products serialization group.

(I don't usually write my configuration via annotations, so hopefully I didn't introduce any unexpected bug, but even if there is an errant typo this should bet you going.)

Upvotes: 1

Related Questions