api-platformmake-dto
Génère des DTOs (input/output) API Platform avec mapping vers les entités
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Génère des DTOs (input/output) API Platform avec mapping vers les entités
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Audite un projet API Platform existant et produit un rapport de bonnes pratiques, performances et sécurité
Génère des filtres API Platform (search, date, range, order, boolean, exists, custom)
Génère un State Processor API Platform pour personnaliser la persistence des données
Génère un State Provider API Platform pour personnaliser la récupération de données
Génère une API Resource complète avec attribut
Génère des tests fonctionnels API Platform (PHPUnit/ApiTestCase) pour une resource
| name | api-platform:make-dto |
| description | Génère des DTOs (input/output) API Platform avec mapping vers les entités |
| argument-hint | <nom-resource> |
| model | sonnet |
| allowed-tools | ["AskUserQuestion","Bash","Read","Write","Edit","Grep","Glob"] |
| version | 1.0.0 |
| license | MIT |
Génère des Data Transfer Objects (DTOs) pour API Platform avec le mapping input/output, les State Providers et Processors associés.
src/Dto/{ResourceName}Input.php (si input)src/Dto/{ResourceName}Output.php (si output)src/State/{ResourceName}Provider.php (si output DTO)src/State/{ResourceName}Processor.php (si input DTO)IMPORTANT : Exécute ce workflow étape par étape :
$ARGUMENTS est fourni, utiliser comme nom de la resourceQuestion: "Pour quelle resource créer des DTOs ?"
Header: "Resource"
src/Entity/Question: "Quel type de DTO créer ?"
Header: "Type"
Options:
- "Input + Output (Recommandé)" : "DTOs distincts pour la lecture et l'écriture"
- "Output uniquement" : "DTO pour personnaliser la représentation en lecture"
- "Input uniquement" : "DTO pour valider et transformer les données en écriture"
composer.json avec Readautoload.psr-4<?php
declare(strict_types=1);
namespace {namespace}\Dto;
final readonly class {ResourceName}Output
{
public function __construct(
public int $id,
// Propriétés exposées en lecture
public string $name,
public string $email,
// Propriétés calculées
public string $displayName,
) {
}
public static function fromEntity({ResourceName} $entity): self
{
return new self(
id: $entity->getId(),
name: $entity->getName(),
email: $entity->getEmail(),
displayName: sprintf('%s (%s)', $entity->getName(), $entity->getEmail()),
);
}
}
<?php
declare(strict_types=1);
namespace {namespace}\Dto;
use Symfony\Component\Validator\Constraints as Assert;
final class {ResourceName}Input
{
public function __construct(
#[Assert\NotBlank]
public readonly string $name,
#[Assert\NotBlank]
#[Assert\Email]
public readonly string $email,
) {
}
public function toEntity(): {ResourceName}
{
// Créer l'entité depuis le DTO
}
public function updateEntity({ResourceName} $entity): {ResourceName}
{
// Mettre à jour l'entité existante
return $entity;
}
}
<?php
declare(strict_types=1);
namespace {namespace}\State;
use ApiPlatform\Metadata\CollectionOperationInterface;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use {namespace}\Dto\{ResourceName}Output;
/**
* @implements ProviderInterface<{ResourceName}Output>
*/
final readonly class {ResourceName}Provider implements ProviderInterface
{
public function __construct(
private ProviderInterface $decorated,
) {
}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
$data = $this->decorated->provide($operation, $uriVariables, $context);
if ($operation instanceof CollectionOperationInterface) {
$items = [];
foreach ($data as $entity) {
$items[] = {ResourceName}Output::fromEntity($entity);
}
return $items;
}
if (null === $data) {
return null;
}
return {ResourceName}Output::fromEntity($data);
}
}
<?php
declare(strict_types=1);
namespace {namespace}\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use {namespace}\Dto\{ResourceName}Input;
use {namespace}\Dto\{ResourceName}Output;
/**
* @implements ProcessorInterface<{ResourceName}Input, {ResourceName}Output>
*/
final readonly class {ResourceName}Processor implements ProcessorInterface
{
public function __construct(
private ProcessorInterface $decorated,
) {
}
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): mixed
{
/** @var {ResourceName}Input $data */
$entity = $data->toEntity();
$result = $this->decorated->process($entity, $operation, $uriVariables, $context);
return {ResourceName}Output::fromEntity($result);
}
}
Modifier l'attribut #[ApiResource] pour utiliser les DTOs :
#[ApiResource(
operations: [
new GetCollection(output: {ResourceName}Output::class),
new Get(output: {ResourceName}Output::class),
new Post(input: {ResourceName}Input::class, output: {ResourceName}Output::class),
new Put(input: {ResourceName}Input::class, output: {ResourceName}Output::class),
new Patch(input: {ResourceName}Input::class, output: {ResourceName}Output::class),
new Delete(),
],
provider: {ResourceName}Provider::class,
processor: {ResourceName}Processor::class,
)]
DTOs générés pour {ResourceName}
Fichiers créés :
- src/Dto/{ResourceName}Input.php
- src/Dto/{ResourceName}Output.php
- src/State/{ResourceName}Provider.php
- src/State/{ResourceName}Processor.php
Mapping :
- Input : POST/PUT/PATCH → {ResourceName}Input → Entité
- Output : Entité → {ResourceName}Output → GET
Prochaines étapes :
- Compléter la logique toEntity() et updateEntity()
- Ajouter des validations sur le DTO Input
- Tester : /api-platform:make-test {ResourceName}
final readonly avec factory method fromEntity()final avec validation Symfony et méthodes toEntity() / updateEntity()readonly)