Symfony API平台:使用组字段搜索筛选器

Symfony API平台:使用组字段搜索筛选器,symfony,serialization,api-platform.com,Symfony,Serialization,Api Platform.com,我正在与API平台合作,我正在寻找一些东西。 我制作了一个人实体,如下所示: 班主任 { /** *@ORM\Id *@ORM\GeneratedValue *@ORM\Columntype=integer */ 私人$id; /** *@ORM\Columntype=string,长度=255 */ 私人$name; /** *@ORM\Columntype=string,长度=255 */ 私人$firstname; /** *@ORM\Columntype=datetime */ 私人$生

我正在与API平台合作,我正在寻找一些东西。 我制作了一个人实体,如下所示:

班主任 { /** *@ORM\Id *@ORM\GeneratedValue *@ORM\Columntype=integer */ 私人$id; /** *@ORM\Columntype=string,长度=255 */ 私人$name; /** *@ORM\Columntype=string,长度=255 */ 私人$firstname; /** *@ORM\Columntype=datetime */ 私人$生日; } 使用已定义的字段组:

App\Entity\Person:
  attributes:
    id:
      groups: ['private']
    name:
      groups: ['public']
    firstname:
      groups: ['public']
    birthdate:
      groups: ['public']
我还指出,如果我想要该资源的所有集合,则只应序列化公共字段:

App\Entity\Person:
    collectionOperations:
      get:
        filters: ['search_filter']
        normalization_context:
          groups: ['public']
        formats: ['json']
如您所见,我应用了搜索过滤器。在这种情况下,我可以从作为查询参数的字段中检索资源

但是,我只想将此筛选器应用于公共字段。 所以我不希望请求工作,因为id字段是私有的

我发现可以精确地将所需的字段作为SearchFilter的参数,但更有用的是精确的组名,因为我打算使用更多的组

我试图查看GroupFilters,但它对我没有帮助,因为它是一个序列化程序筛选器


你给我推荐什么?

经过几个小时的挖掘,我终于找到了答案:

我创建了自己的过滤器,并注入了一个SearchFilter实例。 为了比较发送到QueryParam中的字段组,我必须用AbstractContextawarRefilter类扩展我的过滤器

我将这些组与ClassMetadataFactory类提供的资源/实体元数据信息进行比较。我不得不使用注释语法来代替yaml来编写我的组,否则它们将不会被检测到

如果一个组不在规范化组中,我将抛出一个异常,否则我将离开SearchFilter来执行过滤过程

以下是我的作品:

使用Apiplate\Core\Bridge\Doctrine\Orm\Filter\AbstractContextawarRefilter; 使用ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractFilter; 使用ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; 使用条令\通用\持久性\管理注册表; 使用条令\ORM\QueryBuilder; 使用http\Exception\RuntimeException; 使用Psr\Log\logger接口; 使用Symfony\Component\HttpFoundation\RequestStack; 使用Symfony\Component\Serializer\Mapping\ClassMetadata; 使用Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; /** *类限制组筛选器 *@package-App\Filters */ 类RestrictGroupFilter扩展了AbstractContextawarRefilter { /** *@var$过滤器 */ 私人$filter; 私有$metadataFactory; 公共函数uu constructAbstractFilter$filter,ClassMetadataFactory$metadataFactory,ManagerRegistry$ManagerRegistry,?RequestStack$RequestStack=null,LoggerInterface$logger=null,array$properties=null { 父项::_构造$managerRegistry、$requestStack、$logger、$properties; $this->filter=$filter; $this->metadataFactory=$metadataFactory; } 受保护的函数filterPropertystring$property,$value,QueryBuilder$QueryBuilder,queryNameGenerator接口$queryNameGenerator,字符串$resourceClass,字符串$operationName=null,数组$context=[] { /** *@var$classMetadata类元数据 */ $classMetadata=$this->metadataFactory->getMetadataFor$resourceClass;检索实体类的属性元数据 准备检查上下文组和规范化组 foreach$context[groups]作为$group { if!在数组$group中,$classMetadata->attributesMetadata[$property]->getGroups{//如果在规范化组中找不到一个组 抛出新RuntimeException$属性的组被拒绝。/*已授权的组:。内爆,$context[Groups]*/; } } //如果一切正常,则启用过滤器 $this->filter->filterProperty$属性、$value、$queryBuilder、$queryNameGenerator、$resourceClass、$operationName; } 公共函数getDescriptionstring$resourceClass:array { //TODO:实现getDescription方法。 返回$this->filter->getDescription$resourceClass; } } 有关服务:

    search_filter:
        parent: 'api_platform.doctrine.orm.search_filter'
        tags:   ['api_platform.filter']
        autowire: false
        autoconfigure: false


    'App\Filters\RestrictGroupFilter':
        arguments: [ '@search_filter','@serializer.mapping.class_metadata_factory']