如何在API Platform中用POST实现带JSON参数的搜索集合路由?
问题:在API Platform中创建POST类型的搜索集合路由
我正尝试在API Platform中创建一个采用POST请求的getCollection类型路由,用于执行搜索操作。该路由将接收JSON负载来处理搜索条件,后续还会处理关联关系、排序等功能。
我不想使用GET请求,因为可能会遇到URL长度限制,同时也希望能在Postman这类工具中便捷使用。
已尝试的方案
- API Platform官方的Symfony控制器文档
- Stack Overflow上关于自定义POST操作的旧帖子(已过时)
- API Platform仓库的相关Issue(无法完成数据水合)
现有代码
Chapter资源类与自定义SearchCollection操作
<?php namespace App\ApiResource\V1; use ApiPlatform\Metadata\ApiResource; use App\Api\Utils\ApiResourceInterface; use App\Api\V1\State\Courses\Chapter\ChapterSearchDataProvider as ChapterChapterSearchDataProvider; use App\Entity\Chapter as EntityChapter; use App\Utils\Api\Operations\SearchCollection; use DateTime; #[ApiResource( routePrefix: '/v1', operations: [ new SearchCollection( uriTemplate: '/chapters/search', name: 'chapter_search', provider: ChapterChapterSearchDataProvider::class, input: false, output: Chapter::class, read: false, write: false, deserialize: false, status: 200 ), ] )] class Chapter implements ApiResourceInterface { public string $id; public string $course; public ?string $previousChapter; public ?string $nextChapter; public string $title; public DateTime $createdAt; public DateTime $updatedAt; public function __construct( string $id, string $course, ?string $previousChapter, ?string $nextChapter, string $title, DateTime $createdAt, DateTime $updatedAt ) { $this->id = $id; $this->course = $course; $this->previousChapter = $previousChapter; $this->nextChapter = $nextChapter; $this->title = $title; $this->createdAt = $createdAt; $this->updatedAt = $updatedAt; } public static function getEntityClass() : string { return EntityChapter::class; } } class SearchCollection extends HttpOperation implements CollectionOperationInterface { public function __construct( // ... ) { parent::__construct( method: 'POST', // ... ); } }
ChapterSearchDataProvider数据提供器
<?php namespace App\Api\V1\State\Courses\Chapter; use ApiPlatform\Metadata\Operation; use ApiPlatform\State\ProviderInterface; use App\Api\V1\Mapper\Courses\Chapter\ChapterMapper; use App\ApiResource\V1\Chapter; use App\Repository\ChapterRepository; final class ChapterSearchDataProvider implements ProviderInterface { private ChapterRepository $repository; private ChapterMapper $mapper; public function __construct( ChapterRepository $repository, ChapterMapper $mapper ) { $this->repository = $repository; $this->mapper = $mapper; } /** * Provides data. * * @param array<string, mixed> $uriVariables * @param array<string, mixed>|array{request?: Request, resource_class?: string} $context * * @return T|PartialPaginatorInterface<T>|iterable<T>|null */ public function provide( Operation $operation, array $uriVariables = [], array $context = [] ): object|array|null { $chapters = $this->repository->findAll(); return $this->mapper->fromArray($chapters); } }
内容的提问来源于stack exchange,提问作者vincent clerc
相关产品推荐
相关产品推荐

