Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Ein Custom Output ohne Entity

Ein Custom Output ohne Entity

~14 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026

Kapitel 5 zeigte BEREITS eine ApiResource OHNE Doctrine-Entity als "Hallo-Welt"-Beispiel – dieses Kapitel geht WEITER: eine ECHTE, NÜTZLICHE Statistik-Resource, die AUSSCHLIESSLICH berechnete Daten liefert.

Eine Statistics-ApiResource definieren

api/src/ApiResource/DashboardStatistics.php
<?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;
}

GENAU wie Begruessung aus Kapitel 5: eine EINFACHE PHP-Klasse OHNE #[ORM\Entity]-Attribut, im Verzeichnis src/ApiResource/ statt src/Entity/ – eine gängige Konvention, um NICHT-persistente Ressourcen von ECHTEN Entities zu UNTERSCHEIDEN.

Den Provider implementieren

api/src/State/DashboardStatisticsProvider.php
<?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([]) nutzt die EFFIZIENTE COUNT(*)-Datenbankabfrage aus Doctrines ServiceEntityRepository, statt (wie in Kapitel 59, aus didaktischen Gründen bewusst vereinfacht) eine GESAMTE Collection zu laden.

Den Endpunkt testen

curl -k https://localhost/api/dashboard/statistics -H "Authorization: Bearer $TOKEN"
{
  "totalProjects": 45,
  "totalTasks": 128,
  "completedTasks": 67,
  "completionRate": 52.3
}

Tipp: Der Swagger-UI-Eintrag für diese Resource erscheint AUTOMATISCH, GENAU wie bei JEDER anderen #[ApiResource] – aus Sicht der Dokumentation/des Clients ist es UNERHEBLICH, ob eine Doctrine-Entity oder eine reine PHP-Klasse dahintersteckt.