API Platform 3(Symfony 6)中如何修改响应字段名称?
修改API Platform 3(Symfony 6)分页元数字段名
当然可以,下面提供两种实用方案,按需选择:
方案一:全局修改(推荐,所有分页接口生效)
通过装饰API Platform默认的分页扩展,重写元数字段名:
- 创建自定义分页扩展类
在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); } }
- 注册装饰服务
在config/services.yaml中添加服务配置,让自定义扩展覆盖默认的分页扩展:
services: App\ApiPlatform\Extension\CustomPaginationExtension: decorates: api_platform.state.pagination_extension arguments: ['@.inner']
方案二:单接口修改(仅针对特定API生效)
如果只需要修改某个接口的分页字段,可通过自定义DTO+序列化注解实现:
- 创建分页响应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; }
- 在实体的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 { // 实体字段定义... }
- 实现自定义集合提供者
在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
相关产品推荐
相关产品推荐

