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
相关产品推荐
相关产品推荐

