API Platform v3中ConstraintViolationList的propertyPath翻译问题
解决API Platform v3中ConstraintViolation的propertyPath翻译问题
问题核心
API Platform默认不会自动翻译propertyPath字段——它直接映射实体的属性名,而translation:extract命令仅提取验证消息,不会处理属性路径的翻译逻辑。
解决方案步骤
1. 自定义ConstraintViolationListNormalizer
重写默认序列化器,对propertyPath做翻译处理:
<?php namespace App\Serializer; use ApiPlatform\Serializer\SerializerContextBuilderInterface; use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer as BaseNormalizer; use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Validator\ConstraintViolationListInterface; class ConstraintViolationListNormalizer extends BaseNormalizer { public function __construct( private readonly TranslatorInterface $translator, ?SerializerContextBuilderInterface $serializerContextBuilder = null, string $format = 'json' ) { parent::__construct($serializerContextBuilder, $format); } public function normalize($object, string $format = null, array $context = []): array { $data = parent::normalize($object, $format, $context); $locale = $context['locale'] ?? $this->translator->getLocale(); foreach ($data['violations'] as &$violation) { if (isset($violation['propertyPath'])) { $violation['propertyPath'] = $this->translatePropertyPath($violation['propertyPath'], $locale); } } return $data; } private function translatePropertyPath(string $path, string $locale): string { $parts = explode('.', $path); $translatedParts = []; foreach ($parts as $part) { if (preg_match('/^(\w+)\[(\d+)\]$/', $part, $matches)) { $field = $matches[1]; $index = $matches[2]; $translatedField = $this->translator->trans($field, [], 'validators', $locale); $translatedParts[] = "{$translatedField}[{$index}]"; } else { $translatedParts[] = $this->translator->trans($part, [], 'validators', $locale); } } return implode('.', $translatedParts); } public function supportsNormalization($data, string $format = null, array $context = []): bool { return $data instanceof ConstraintViolationListInterface && $format === $this->format; } }
2. 注册自定义Normalizer
在config/services.yaml中配置服务,确保优先级高于默认序列化器:
services: App\Serializer\ConstraintViolationListNormalizer: arguments: $translator: '@translator' $serializerContextBuilder: '@api_platform.serializer.context_builder' tags: - { name: serializer.normalizer, priority: 100 }
3. 补充属性名翻译
在translations/validators.es.yaml中添加对应属性的翻译键:
phones: teléfonos number: número
4. 验证效果
发送POST请求时携带Accept-Language: es,此时propertyPath会被翻译为teléfonos[0].número。
可选优化
如果希望展示更友好的名称(如“número de teléfono”),可以修改translatePropertyPath方法,直接返回翻译后的友好名称,或者在响应中新增translatedField字段单独展示,避免破坏原有propertyPath的结构。
内容的提问来源于stack exchange,提问作者Matías Cánepa
相关产品推荐
相关产品推荐

