lshamanl/symfony-ui-bundle-query

该包已被弃用且不再维护。作者建议使用intellect-web-development/symfony-presentation-bundle包代替。

Symfony UI Bundle Query (筛选、排序、分页、单个资源)

安装: 128

依赖者: 0

建议者: 0

安全: 0

星星: 0

关注者: 1

分支: 0

开放问题: 0

类型:symfony-bundle

0.3.1 2022-01-07 15:21 UTC

This package is auto-updated.

Last update: 2022-09-18 15:37:53 UTC


README

描述

此包是Symfoni-bundle。

此包解决的问题:减少开发者编写UI入口点(控制器、CommandBus)等重复代码的需要,例如控制器。

外部使用示例

查询字符串示例

GET /clients?filter[emails.email][like]=26d@&sort=-createdAt,updatedAt&page[number]=1&page[size]=20&filter[userId][eq]=ccf92b7a-8e05-4f4b-9f0a-e4360dbacb23&filter[name.translations.last][eq]=Tesla&lang=ru

合同

排序

描述

排序由"sort"参数指定。排序方向由名称前可选的'-'符号指定。如果存在'-',则按该字段排序使用DESC修饰符,否则使用ASC。允许对多个聚合字段进行排序。要这样做,需要写几个字段,并用','分隔。越早指定的字段,在选择时权重越大。

示例
sort='-createdAt,updatedAt'

分页

描述

分页由"page"参数指定。参数有两个字段 - number和size。

  • "number"指定客户端请求的页码。默认值:1
  • "size"指定页面大小(应显示多少聚合)。默认值:20
描述
page[number]='1'
page[size]='20'

筛选

描述

搜索运算符

名称 允许值 示例 描述
NOT_IN 'not-in' filter[status][not-in][]='blocked' 属性不包含指定的任何值
IN 'in' filter[status][in][]='active' 属性包含指定的任何值
RANGE 'range' filter[rating][range]='17,42' 属性位于指定的选择范围内
IS_NULL 'is-null' filter[gender][is-null] 属性等于null
NOT_NULL 'not-null' filter[name][not-null] 属性不等于null
LESS_THAN 'less-than', '<', 'lt' filter[rating][<]='94' 属性小于指定值
GREATER_THAN 'greater-than', '>', 'gt' filter[rating][>]='42' 属性大于指定值
LESS_OR_EQUALS 'less-or-equals', '<=', 'lte' filter[rating][<=]='15' 属性小于或等于指定值
GREATER_OR_EQUALS 'greater-or-equals', '>=', 'gte' filter[rating][>=]='97' 属性大于或等于指定值
LIKE 'like' filter[email][like]='26d@' 属性包含指定值的一部分
NOT_LIKE 'not-like' filter[email][not-like]='27d@' 属性不包含指定值的一部分
EQUALS 'equals', '=', 'eq' filter[userId][eq]='ccf92b7a-8e05-4f4b-9f0a-e4360dbacb23' 属性等于指定值
NOT_EQUALS 'not-equals', '!=', '<>', 'neq' filter[userId][neq]='aaf92b7a-8e05-4f4b-9f0a-e4360dbacb23' 属性不等于指定值
示例
filter[userId][eq]='ccf92b7a-8e05-4f4b-9f0a-e4360dbacb23'
filter[name.translations.last][eq]='Tesla'
filter[emails.email][like]='26d@'
filter[userId][eq]='ccf92b7a-8e05-4f4b-9f0a-e4360dbacb23'
filter[name.translations.last][eq]='Tesla'
filter[emails.email][in][]='0791d11b6a952a3804e7cb8a220d0a9b@mail.ru'
filter[emails.email][in][]='0891d11b6a952a3804e7cb8a220d0a9b@mail.ru'

内部使用

查询

聚合

读取操作的示例

use App\Path\To\Entity;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Nelmio\ApiDocBundle\Annotation\Model;
use SymfonyBundle\UIBundle\Foundation\Core\Contract\ApiFormatter;
use SymfonyBundle\UIBundle\Foundation\Core\Dto\OutputFormat;
use SymfonyBundle\UIBundle\Query\Core\CQRS\Query\Aggregate\Processor as AggregateProcessor;
use SymfonyBundle\UIBundle\Query\Core\CQRS\Query\Aggregate\Context as AggregateContext;

class Controller {
    /**
     * @Route("/{id}.{_format}", methods={"GET"}, name=".read", defaults={"_format"="json"})
     * @OA\Response(
     *     response=200,
     *     description="Read Entity",
     *     @OA\JsonContent(
     *         allOf={
     *             @OA\Schema(ref=@Model(type=ApiFormatter::class)),
     *             @OA\Schema(type="object",
     *                 @OA\Property(
     *                     property="data",
     *                     type="object",
     *                     @OA\Property(
     *                         property="entity",
     *                         ref=@Model(type=UseCase\CommonOutputContract::class)
     *                     )
     *                 ),
     *                 @OA\Property(
     *                     property="status",
     *                     example="200"
     *                )
     *             )
     *         }
     *     )
     * )
     */
    public function read(
        string $id,
        AggregateProcessor $processor,
        OutputFormat $outputFormat
    ): Response {
        $context = new AggregateContext(
            outputFormat: $outputFormat->getFormat(),
            entityId: $id,
            targetEntityClass: User::class,
            outputDtoClass: UseCase\CommonOutputContract::class,
        );

        $processor->process($context);
        return $processor->makeResponse();
    }

搜索

搜索操作的示例

use App\Path\To\Entity;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Nelmio\ApiDocBundle\Annotation\Model;
use SymfonyBundle\UIBundle\Foundation\Core\Contract\ApiFormatter;
use SymfonyBundle\UIBundle\Foundation\Core\Dto\OutputFormat;
use SymfonyBundle\UIBundle\Query\Core\Contract\Filter\FilterSortPagination;
use SymfonyBundle\UIBundle\Query\Core\CQRS\Query\Search\Processor as SearchProcessor;
use SymfonyBundle\UIBundle\Query\Core\CQRS\Query\Search\Context as SearchContext;
use SymfonyBundle\UIBundle\Query\Core\Service\Filter\SearchQuery;

class Controller {
    /**
     * @Route(".{_format}", methods={"GET"}, name=".search", defaults={"_format"="json"})
     * @OA\Get(
     *     @OA\Parameter(
     *          name="searchParams",
     *          in="query",
     *          required=false,
     *          @OA\Schema(
     *              ref=@Model(type=FilterSortPagination::class)
     *          ),
     *     )
     * )
     * @OA\Response(
     *     response=200,
     *     description="Search by Users",
     *     @OA\JsonContent(
     *          allOf={
     *              @OA\Schema(ref=@Model(type=ApiFormatter::class)),
     *              @OA\Schema(type="object",
     *                  @OA\Property(
     *                      property="data",
     *                      type="object",
     *                      @OA\Property(
     *                          property="entities",
     *                          ref=@Model(type=UseCase\CommonOutputContract::class)
     *                      )
     *                  ),
     *                  @OA\Property(
     *                      property="status",
     *                      example="200"
     *                 )
     *              )
     *          }
     *      )
     * )
     */
    public function search(
        SearchProcessor $processor,
        SearchQuery $searchQuery,
        OutputFormat $outputFormat
    ): Response {
        $context = new SearchContext(
            targetEntityClass: User::class,
            outputFormat: $outputFormat->getFormat(),
            outputDtoClass: UseCase\CommonOutputContract::class,
            filterBlackList: ['id'],
            pagination: $searchQuery->getPagination(),
            filters: $searchQuery->getFilters(),
            sorts: $searchQuery->getSorts()
        );

        $processor->process($context);

        return $processor->makeResponse();
    }
}