Activating Only Selected Operations
Activating Only Selected Operations
~15 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
NOT every resource should be FULLY writable. As a CONCRETE example we introduce a SECOND entity: Tag – reference data created ONLY via fixtures (chapter 15), NEVER through the API.
Creating the Tag entity
docker compose exec php bin/console make:entity Tag<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use App\Repository\TagRepository;
use Doctrine\ORM\Mapping as ORM;
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
]
)]
#[ORM\Entity(repositoryClass: TagRepository::class)]
class Tag
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 100, unique: true)]
private string $name = '';
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
}ONLY TWO classes in the operations list: GetCollection and Get. Post, Put, Patch, and Delete are COMPLETELY missing – API Platform generates NO route whatsoever for them.
Testing the behavior
curl -k -X POST https://localhost/api/tags \
-H 'Content-Type: application/json' \
-d '{"name": "Urgent"}'{
"@context": "/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "No route found for \"POST /api/tags\""
}Achtung: Status 404 Not Found, NOT 405 Method Not Allowed – from the router's perspective, the route for POST /api/tags simply does NOT exist, since it was NEVER registered.
When read-only resources pay off
- Reference/lookup data (tags, categories, status values) maintained centrally via fixtures or an admin panel.
- Computed or aggregated data (e.g. a statistics resource) where writing CONCEPTUALLY makes no sense.
- Data from EXTERNAL systems that API Platform should only MIRROR, not MODIFY.
Even tighter: only GetCollection, no Get
Just as easily, Get can be LEFT OUT, keeping ONLY GetCollection – then ONLY GET /api/tags exists, but NO GET /api/tags/{id} for a single item. In practice this is RARELY useful, but it shows how GRANULARLY the list can be controlled.
Tipp: The ApiResource::$operations property is a SIMPLE PHP list – any familiar control structure (conditions, loops when generating config) works just like with ANY other PHP array, there is NO special DSL.