A Custom Output Without an Entity
A Custom Output Without an Entity
~14 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
Chapter 5 ALREADY showed an ApiResource WITHOUT a Doctrine entity as a "hello world" example – this chapter goes FURTHER: a REAL, USEFUL statistics resource that delivers EXCLUSIVELY computed data.
Defining a statistics ApiResource
<?php
declare(strict_types=1);
namespace App\ApiResource;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use App\State\DashboardStatisticsProvider;
#[ApiResource(
operations: [
new Get(
uriTemplate: '/dashboard/statistics',
provider: DashboardStatisticsProvider::class,
),
]
)]
final class DashboardStatistics
{
public int $totalProjects;
public int $totalTasks;
public int $completedTasks;
public float $completionRate;
}EXACTLY like Begruessung from chapter 5: a SIMPLE PHP class WITHOUT an #[ORM\Entity] attribute, in the src/ApiResource/ directory instead of src/Entity/ – a common convention to DISTINGUISH non-persistent resources from REAL entities.
Implementing the provider
<?php
declare(strict_types=1);
namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\ApiResource\DashboardStatistics;
use App\Repository\ProjectRepository;
use App\Repository\TaskRepository;
final class DashboardStatisticsProvider implements ProviderInterface
{
public function __construct(
private readonly ProjectRepository $projectRepository,
private readonly TaskRepository $taskRepository,
) {
}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): DashboardStatistics
{
$totalTasks = $this->taskRepository->count([]);
$completedTasks = $this->taskRepository->count(['done' => true]);
$stats = new DashboardStatistics();
$stats->totalProjects = $this->projectRepository->count([]);
$stats->totalTasks = $totalTasks;
$stats->completedTasks = $completedTasks;
$stats->completionRate = $totalTasks > 0
? round($completedTasks / $totalTasks * 100, 1)
: 0.0;
return $stats;
}
}count([]) uses the EFFICIENT COUNT(*) database query from Doctrine's ServiceEntityRepository, instead of (as in chapter 59, deliberately simplified for didactic reasons) loading an ENTIRE collection.
Testing the endpoint
curl -k https://localhost/api/dashboard/statistics -H "Authorization: Bearer $TOKEN"{
"totalProjects": 45,
"totalTasks": 128,
"completedTasks": 67,
"completionRate": 52.3
}Tipp: The Swagger UI entry for this resource appears AUTOMATICALLY, EXACTLY as for ANY other #[ApiResource] – from a documentation/client perspective, it is IRRELEVANT whether a Doctrine entity or a plain PHP class is behind it.