您可以try 创建一个custom normalizer来修改序列化过程,并确保@context
、@id
和@type
的设置符合您的要求.
namespace App\Serializer;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class TransitionNormalizer implements ContextAwareNormalizerInterface
{
private $decorated;
public function __construct(NormalizerInterface $decorated)
{
$this->decorated = $decorated;
}
public function normalize($object, string $format = null, array $context = [])
{
$data = $this->decorated->normalize($object, $format, $context);
$data['@context'] = '/contexts/Transition';
$data['@id'] = '/transitions/' . $object->id;
$data['@type'] = 'https://schema.org/UpdateAction';
return $data;
}
public function supportsNormalization($data, string $format = null, array $context = []): bool
{
return $data instanceof Transition;
}
}
将自定义规范化器as a service和tag it定义为serializer.normalizer
.这将确保它是在Symfony Serializer component注册.
# config/services.yaml
services:
App\Serializer\TransitionNormalizer:
decorates: 'serializer.normalizer.object'
tags: ['serializer.normalizer']
并更新Transition
类上的ApiResource
annotation以利用自定义规范化器.
#[ApiResource(
types: 'https://schema.org/UpdateAction',
provider: TransitionStateProvider::class,
normalizationContext: ['groups' => ['transition']]
)]
class Transition
{
#[ApiProperty(
identifier: true,
types: ['https://schema.org/identifier'],
)]
public int $id;
}
你得到的工作流程:
+---------------+ +----------------------+ +-----------------------+ +-------------------+
| API Resource | | Custom Normalizer | | Service Definition | | Desired JSON-LD |
| Transition | --> | TransitionNormalizer | --> | serializer.normalizer | --> | @context Setup |
+---------------+ +----------------------+ +-----------------------+ +-------------------+
你更新的代码与上面的建议:
namespace App\Serializer;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class TransitionNormalizer implements ContextAwareNormalizerInterface
{
private $decorated;
public function __construct(NormalizerInterface $decorated)
{
$this->decorated = $decorated;
}
public function normalize($object, string $format = null, array $context = [])
{
$data = $this->decorated->normalize($object, $format, $context);
$data['@context'] = '/contexts/Transition';
$data['@id'] = '/transitions/' . $object->id;
$data['@type'] = 'https://schema.org/UpdateAction';
return $data;
}
public function supportsNormalization($data, string $format = null, array $context = []): bool
{
return $data instanceof Transition;
}
}
// config/services.yaml
services:
App\Serializer\TransitionNormalizer:
decorates: 'serializer.normalizer.object'
tags: ['serializer.normalizer']
// Your ApiResource and Provider remains the same
#[ApiResource(
types: 'https://schema.org/UpdateAction',
provider: TransitionStateProvider::class,
normalizationContext: ['groups' => ['transition']]
)]
class Transition
{
#[ApiProperty(
identifier: true,
types: ['https://schema.org/identifier'],
)]
public int $id;
}
class TransitionStateProvider implements ProviderInterface
{
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
$transition = new Transition();
$transition->id = 1;
return $transition;
}
}