You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何扩展Hydra搜索上下文以在客户端生成筛选字段?

解决方案

方法1:自定义筛选器扩展元数据

创建自定义筛选器子类,在其中为特定字段添加自定义元数据,这些元数据会被Hydra纳入响应中:

use ApiPlatform\Doctrine\Orm\Filter\DateFilter;

class CustomDateFilter extends DateFilter
{
    public function getDescription(string $resourceClass): array
    {
        $description = parent::getDescription($resourceClass);
        
        // 为不同字段标记自定义类型
        foreach ($description as $key => &$data) {
            if (str_starts_with($key, 'createdAt')) {
                $data['custom_type'] = 'range_date_picker';
            } elseif (str_starts_with($key, 'birthdate')) {
                $data['custom_type'] = 'single_date_picker';
            }
        }
        
        return $description;
    }
}

在实体中替换原筛选器使用自定义版本:

class Entity
{
  #[ApiFilter(CustomDateFilter::class, properties: ['createdAt'])]
  protected ?DateTimeInterface $createdAt = null;
  
  #[ApiFilter(CustomDateFilter::class, properties: ['birthdate'])]
  protected ?DateTimeInterface $birthdate = null;
}

方法2:通过自定义序列化器注入上下文信息

  1. 在ApiResource的操作中定义自定义Hydra上下文:
#[ApiResource(
    operations: [
        new GetCollection(
            hydraContext: [
                'filter_metadata' => [
                    'createdAt' => ['type' => 'range_date_picker'],
                    'birthdate' => ['type' => 'single_date_picker']
                ]
            ]
        )
    ]
)]
  1. 创建自定义序列化器,将上下文信息注入到Hydra的搜索元数据中:
use ApiPlatform\Hydra\Serializer\CollectionFiltersNormalizer;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;

class CustomHydraCollectionFiltersNormalizer implements ContextAwareNormalizerInterface, NormalizerAwareInterface
{
    use NormalizerAwareTrait;
    
    public function normalize($object, string $format = null, array $context = []): array
    {
        $data = $this->normalizer->normalize($object, $format, $context);
        
        // 从操作上下文取自定义元数据,追加到hydra:mapping中
        if (isset($context['operation']?->getHydraContext()['filter_metadata'])) {
            $filterMetadata = $context['operation']->getHydraContext()['filter_metadata'];
            
            foreach ($data['hydra:search']['hydra:mapping'] as &$mapping) {
                $property = $mapping['property'];
                if (isset($filterMetadata[$property])) {
                    $mapping['custom_metadata'] = $filterMetadata[$property];
                }
            }
        }
        
        return $data;
    }
    
    public function supportsNormalization($data, string $format = null, array $context = []): bool
    {
        return $this->normalizer instanceof ContextAwareNormalizerInterface && $this->normalizer->supportsNormalization($data, $format, $context);
    }
}
  1. 在services.yaml注册该序列化器,确保优先级高于默认的集合筛选器归一化器:
services:
    App\Serializer\CustomHydraCollectionFiltersNormalizer:
        tags:
            - { name: serializer.normalizer, priority: 100 }

方法3:扩展Hydra元数据生成器

若需全局生效的自定义元数据,可扩展ApiPlatform\Hydra\Serializer\HydraSerializer或ApiPlatform\Metadata\Resource\Factory\ResourceMetadataFactoryInterface,在元数据生成阶段直接插入自定义字段。


内容的提问来源于stack exchange,提问作者Stephan Vierkant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 10:50:16