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

Api Platform 3.0:定义带Provider/Processor的Post子资源路由及获取Client实例

Api Platform 2.7子资源Post请求获取关联Client实例解决方案

问题场景

我们后端采用资源与实体分离架构,已从Api Platform 2.6通过php bin/console api:upgrade-resource命令升级至2.7(目标版本3.0)。当前在创建子资源时,遇到带Provider、Processor和自定义控制器的Post请求无法正确获取关联Client实例的问题。

现有Basket资源路由配置:

#[ApiResource(
    uriTemplate: '/clients/{id}/baskets.{_format}',
    processor: BasketDataPersister::class,
    provider : ClientDataProvider::class,
    status: 200,
    denormalizationContext: ['groups' => ['write', 'write:Basket']],
    normalizationContext: ['groups' => ['read', 'read:Basket']],
    operations: [
        new Post(controller: PostClientBasketController::class, normalizationContext: ['groups' => ['read', 'read:Basket']], denormalizationContext: ['groups' => ['write', 'write:Basket']], security: 'is_granted(\'ROLE_USER\')', requirements: ['id' => '^[a-fA-F0-9]{12}$']),
    ],
)]

控制器需要接收Client实例:

public function __invoke(Client $data, Request $request, ?string $_format): Basket|JsonResponse
{
    /** @var Basket $basket */
    $basket = $this->serializer->deserialize($request->getContent(), Basket::class, $_format);
    $basket
        ->setClient($data->getId())
        ->setOrganizationId($data->getOrganizationId())
    ;

    return $basket;
}

此前尝试配置uriVariables关联Client资源但未生效:

uriVariables: ['id' => new Link(
        fromClass: \App\Resource\Client::class,
        identifiers: ['id']
    )],

解决步骤

1. 正确配置uriVariables关联Client资源

将uriVariables配置放到ApiResource注解的顶层,确保路由参数与Client资源正确绑定:

#[ApiResource(
    uriTemplate: '/clients/{id}/baskets.{_format}',
    processor: BasketDataPersister::class,
    provider : ClientDataProvider::class,
    status: 200,
    denormalizationContext: ['groups' => ['write', 'write:Basket']],
    normalizationContext: ['groups' => ['read', 'read:Basket']],
    // 新增正确的uriVariables配置
    uriVariables: [
        'id' => new Link(
            fromClass: \App\Resource\Client::class,
            identifiers: ['id']
        )
    ],
    operations: [
        new Post(controller: PostClientBasketController::class, normalizationContext: ['groups' => ['read', 'read:Basket']], denormalizationContext: ['groups' => ['write', 'write:Basket']], security: 'is_granted(\'ROLE_USER\')', requirements: ['id' => '^[a-fA-F0-9]{12}$']),
    ],
)]

2. 确保Client资源已被Api Platform管理

Client类必须添加#[ApiResource]注解,否则Api Platform无法识别该资源类型,无法完成实例注入:

#[ApiResource(
    // 根据需求配置Client资源的操作、序列化组等
)]
class Client
{
    // 类定义
}

3. 验证ClientDataProvider实现

确保ClientDataProvider正确实现ProviderInterface,能够根据传入的标识符获取对应的Client实例:

class ClientDataProvider implements ProviderInterface
{
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
    {
        // 实现根据$uriVariables['id']获取Client实例的逻辑
    }
}

4. 控制器参数接收

控制器的__invoke方法中直接声明Client类型参数即可,Api Platform会自动根据路由参数注入匹配的实例,无需额外处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:45:29