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

API Platform 3(Symfony 6)中如何修改响应字段名称?

修改API Platform 3(Symfony 6)分页元数字段名

当然可以,下面提供两种实用方案,按需选择:

方案一:全局修改(推荐,所有分页接口生效)

通过装饰API Platform默认的分页扩展,重写元数字段名:

  1. 创建自定义分页扩展类
    在src/ApiPlatform/Extension下新建CustomPaginationExtension.php:
<?php

namespace App\ApiPlatform\Extension;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\Pagination\PaginationExtensionInterface;
use ApiPlatform\State\Pagination\PaginatorInterface;
use Symfony\Component\Serializer\Annotation\SerializedName;

class CustomPaginationExtension implements PaginationExtensionInterface
{
    public function __construct(private readonly PaginationExtensionInterface $decorated)
    {
    }

    public function supportsResult(mixed $result, Operation $operation, array $uriVariables = [], array $context = []): bool
    {
        return $this->decorated->supportsResult($result, $operation, $uriVariables, $context);
    }

    public function getResult(mixed $result, Operation $operation, array $uriVariables = [], array $context = []): mixed
    {
        $paginatedResult = $this->decorated->getResult($result, $operation, $uriVariables, $context);

        if ($paginatedResult instanceof PaginatorInterface) {
            return new class($paginatedResult) implements PaginatorInterface {
                public function __construct(private readonly PaginatorInterface $paginator)
                {
                }

                #[SerializedName('total_items')]
                public function getTotalItems(): float
                {
                    return $this->paginator->getTotalItems();
                }

                #[SerializedName('page_size')]
                public function getPageSize(): float
                {
                    return $this->paginator->getItemsPerPage();
                }

                // 以下是PaginatorInterface必需的方法,直接委托给原分页器
                public function count(): int
                {
                    return $this->paginator->count();
                }

                public function getCurrentPage(): float
                {
                    return $this->paginator->getCurrentPage();
                }

                public function getLastPage(): float
                {
                    return $this->paginator->getLastPage();
                }

                public function getIterator(): \Traversable
                {
                    return $this->paginator->getIterator();
                }

                public function current(): mixed
                {
                    return $this->paginator->current();
                }

                public function next(): void
                {
                    $this->paginator->next();
                }

                public function key(): int
                {
                    return $this->paginator->key();
                }

                public function valid(): bool
                {
                    return $this->paginator->valid();
                }

                public function rewind(): void
                {
                    $this->paginator->rewind();
                }
            };
        }

        return $paginatedResult;
    }

    public function supportsPagination(Operation $operation, array $context = []): bool
    {
        return $this->decorated->supportsPagination($operation, $context);
    }

    public function getPagination(Operation $operation, array $context = []): array
    {
        return $this->decorated->getPagination($operation, $context);
    }
}
  1. 注册装饰服务
    在config/services.yaml中添加服务配置,让自定义扩展覆盖默认的分页扩展:
services:
    App\ApiPlatform\Extension\CustomPaginationExtension:
        decorates: api_platform.state.pagination_extension
        arguments: ['@.inner']

方案二:单接口修改(仅针对特定API生效)

如果只需要修改某个接口的分页字段,可通过自定义DTO+序列化注解实现:

  1. 创建分页响应DTO
    在src/Dto下新建PaginatedResponse.php:
<?php

namespace App\Dto;

use ApiPlatform\Metadata\ApiProperty;
use Symfony\Component\Serializer\Annotation\SerializedName;

class PaginatedResponse
{
    #[SerializedName('total_items')]
    #[ApiProperty(readable: true)]
    public int $totalItems;

    #[SerializedName('page_size')]
    #[ApiProperty(readable: true)]
    public int $itemsPerPage;

    /** @var array<object> */
    public array $items;
}
  1. 在实体的API配置中指定输出为该DTO
    修改实体的ApiResource注解,为目标操作指定输出类,并关联自定义提供者:
<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GetCollection;
use App\Dto\PaginatedResponse;
use App\State\YourEntityCollectionProvider;

#[ApiResource(
    operations: [
        new GetCollection(
            output: PaginatedResponse::class,
            provider: YourEntityCollectionProvider::class
        )
    ]
)]
class YourEntity
{
    // 实体字段定义...
}
  1. 实现自定义集合提供者
    在src/State下新建YourEntityCollectionProvider.php,负责查询数据并组装成DTO:
<?php

namespace App\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Dto\PaginatedResponse;
use App\Entity\YourEntity;
use Doctrine\ORM\EntityManagerInterface;

class YourEntityCollectionProvider implements ProviderInterface
{
    public function __construct(private readonly EntityManagerInterface $em)
    {
    }

    public function provide(Operation $operation, array $uriVariables = [], array $context = []): PaginatedResponse
    {
        $repository = $this->em->getRepository(YourEntity::class);
        $page = $context['filters']['page'] ?? 1;
        $pageSize = $context['filters']['itemsPerPage'] ?? 10;

        $queryBuilder = $repository->createQueryBuilder('e');
        $totalItems = $queryBuilder->select('COUNT(e.id)')->getQuery()->getSingleScalarResult();
        $items = $queryBuilder->setFirstResult(($page - 1) * $pageSize)->setMaxResults($pageSize)->getQuery()->getResult();

        $response = new PaginatedResponse();
        $response->totalItems = (int)$totalItems;
        $response->itemsPerPage = $pageSize;
        $response->items = $items;

        return $response;
    }
}

内容的提问来源于stack exchange,提问作者Marko Askovic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:36:00