версия
symfony
7.4
symfony/object-mapper
7.4
api-platform/symfony
4.2
php
8.4
Опишите проблему
Итак, я читал о новой рекомендации для платформы API, которая заключается в использовании и сопоставлении DTO вместо записи метаданных ресурсов платформы API напрямую через сущность.
См. также https://api-platform.com/docs/core/dto/
Итак, Я пытался реализовать это, но пока безуспешно.
Проиллюстрируйте проблему с помощью моего кода
Вот моя простая сущность:
Код: Выделить всё
# src/Entity
namespace App\Entity;
#[ORM\Entity(repositoryClass: CompanyRepository::class)]
#[ORM\Table(name: 'company')]
class Company
{
use TimestampableEntity;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: Types::BIGINT)]
#[Groups(['read:company'])]
private ?int $id = null;
#[ORM\Column(type: Types::STRING, length: 255)]
#[Groups(['read:company'])]
private string $name = '';
...
}
Код: Выделить всё
# src/Domain/Company/ApiResource
namespace App\Domain\Company\ApiResource;
use ApiPlatform\Doctrine\Orm\State\Options;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Post;
use App\Entity\Company;
use Symfony\Component\ObjectMapper\Attribute\Map;
use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource(
operations: [
new Post(
uriTemplate: '/company',
/** @todo security: 'is_granted("ROLE_ADMIN")', */
normalizationContext: ['groups' => ['read:company']],
output: CompanyCreateOutput::class,
name: 'create_company',
),
],
stateOptions: new Options(entityClass: Company::class),
)]
#[Map(target: Company::class)]
class CompanyCreateInput
{
public string $name = '';
}
Код: Выделить всё
# src/Domain/Company/ApiResource
namespace App\Domain\Company\ApiResource;
use App\Entity\Company;
use Symfony\Component\ObjectMapper\Attribute\Map;
use Symfony\Component\Serializer\Attribute\Groups;
#[Map(source: Company::class)]
class CompanyCreateOutput
{
#[Groups(['read:company'])]
public int $id;
#[Groups(['read:company'])]
public string $name;
#[Groups(['read:company'])]
#[Map(source: 'created_at')]
public string $createdAt;
}
Код: Выделить всё
POST {{url}}/company
{
"name": "This is a test"
}
Код: Выделить всё
{
"@context": {
"@vocab": "https://api.project.local/api/docs.jsonld#",
"hydra": "http://www.w3.org/ns/hydra/core#",
"name": "CompanyCreateInput/name"
},
"@type": "CompanyCreateInput",
"@id": "/api/.well-known/genid/28ed6cfb3faf268d111c"
}
Что я пытаюсь получить
Я хочу, чтобы при создании ресурса (с помощью POST) он возвращал созданный ресурс, например:
Код: Выделить всё
{
"id": 12345,
"name": This is a test",
"created_at": "29/12/2025 00:00:00"
}
- Я читал, как нормализовать объект стандартным способом с помощью ItemNormalizer::normalize, который включает выходной аргумент, но не использует его... Мне кажется, это ошибка...
- Я пытался создать собственный поставщик CompanyCreateRepresentationProvider, но я не знал, как его использовать, и похоже, что он действительно не используется...
Подробнее здесь: https://stackoverflow.com/questions/798 ... rehensible
Мобильная версия