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

API Platform 2.7 GraphQL自定义Query无法指定Output类型求助

解决API Platform 2.7 GraphQL自定义Query返回指定Output类型的问题

问题原因

在API Platform 2.7中,为实体(如User)的ApiResource添加GraphQL自定义Query时,框架会默认将Query与该实体类型关联,即使设置了output参数也可能被覆盖;同时如果目标Output类未被标记为GraphQL可识别类型,也会导致返回类型不生效。

解决方案

1. 标记Output类为GraphQL类型

确保MyFullPerimeterOutput被API Platform识别为GraphQL类型,添加#[GraphQLType]注解:

<?php
namespace App\Dto;

use ApiPlatform\Metadata\GraphQL\GraphQLType;
use Symfony\Component\Serializer\Annotation\Groups;

#[GraphQLType(name: 'MyFullPerimeterOutput')]
class MyFullPerimeterOutput
{
    #[Groups(['user_my_full_perimeter'])]
    public string $username;

    #[Groups(['user_my_full_perimeter'])]
    public array $permissions;

    // 其他业务字段...
}

2. 修正GraphQL Query配置

在User的ApiResource中定义Query时,显式指定type参数覆盖默认的实体关联,同时确保output参数正确设置:

new Query(
    name: 'myFullPerimeter',
    security: "is_granted('ROLE_USER')",
    output: MyFullPerimeterOutput::class,
    type: MyFullPerimeterOutput::class, // 显式指定返回的GraphQL类型
    normalizationContext: ['groups' => ['user_my_full_perimeter']],
    provider: UserProvider::class
),

3. 确保Provider返回Output实例

修改UserProvider,使其返回MyFullPerimeterOutput实例而非User实体:

<?php
namespace App\Provider;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Dto\MyFullPerimeterOutput;
use Symfony\Component\Security\Core\Security;

class UserProvider implements ProviderInterface
{
    public function __construct(private Security $security) {}

    public function provide(Operation $operation, array $uriVariables = [], array $context = []): MyFullPerimeterOutput
    {
        $currentUser = $this->security->getUser();
        
        $output = new MyFullPerimeterOutput();
        $output->username = $currentUser->getUsername();
        $output->permissions = $currentUser->getPermissions();
        // 填充其他字段逻辑...

        return $output;
    }
}

替代方案:独立定义Output的ApiResource

如果不想将Query关联到User实体,可以直接为MyFullPerimeterOutput创建ApiResource,这样生成的Query会直接返回目标类型:

<?php
namespace App\Dto;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GraphQL\Query;
use App\Provider\UserProvider;

#[ApiResource(
    graphql: [
        new Query(
            name: 'myFullPerimeter',
            security: "is_granted('ROLE_USER')",
            normalizationContext: ['groups' => ['user_my_full_perimeter']],
            provider: UserProvider::class
        )
    ]
)]
#[GraphQLType(name: 'MyFullPerimeterOutput')]
class MyFullPerimeterOutput
{
    // 字段定义...
}

验证

修改完成后,清除API Platform缓存(php bin/console cache:clear),打开GraphQL Playground即可看到myFullPerimeter查询返回的是MyFullPerimeterOutput类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:35:30