如何在api平台GET操作中始终对特定字段值过滤集合?

时间:2019-09-02 19:06:34

标签: api-platform.com

在GET操作中,我想从返回的集合中排除我的实体,这些实体的“ archive”字段等于“ true”。

我希望将其作为/ users或/ companies等端点的默认值,并且我想避免像/users?filter[archive]=true这样手动添加URL过滤器

什么是最好的方法?

感谢您的帮助:)

1 个答案:

答案 0 :(得分:1)

我必须做类似的事情,我通过对集合应用DoctrineExtension来解决此问题,该集合会将WHERE子句添加到QueryBuilder。

如何?

  1. 定义您的过滤器,我看到您已经拥有它。
  2. 仅将“ Doctrine Extension”(扩展名)添加到“ by by”(仅适用于集合),或者在需要时也应用于以下项:https://api-platform.com/docs/core/extensions/#custom-doctrine-orm-extension
services:
    App\Doctrine\Extension\ArchivedExtension:
        tags:
            - { name: api_platform.doctrine.orm.query_extension.collection }
  1. 为您的扩展程序编码。

您可以检查是否接收到某个“过滤器”(您的“ filter [archive] = true”查询参数):如果是,则不将条件应用于QueryBuilder,您的过滤器将通过Api平台。

您的扩展程序类应如下所示:

class ArchivedExtension implements QueryCollectionExtensionInterface
{
    public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null, array $context = [])
    {
        $this->addWhere($queryBuilder, $resourceClass, $context);
    }

    private function addWhere(QueryBuilder $queryBuilder, string $resourceClass, array $context = [])
    {
        if (MyResource::class !== $resourceClass) {
            return;
        }

        // Search if a "archive" Filter is being requested, if not, apply a restriction to the QueryBuilder
        if (array_key_exists('archive', $context['filters'])) {
            return;
        }

        $rootAlias = $queryBuilder->getRootAliases()[0];
        $queryBuilder->andWhere(sprintf('%s.archive = :archive', $rootAlias));
        $queryBuilder->setParameter('archive', true);
    }
}