fix(graphql): use right nested operation#5102
Conversation
85e4479 to
ee8fc86
Compare
| final class FieldsBuilder implements FieldsBuilderInterface | ||
| { | ||
| public function __construct(private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, private readonly PropertyMetadataFactoryInterface $propertyMetadataFactory, private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, private readonly ResourceClassResolverInterface $resourceClassResolver, private readonly TypesContainerInterface $typesContainer, private readonly TypeBuilderInterface $typeBuilder, private readonly TypeConverterInterface $typeConverter, private readonly ResolverFactoryInterface $itemResolverFactory, private readonly ResolverFactoryInterface $collectionResolverFactory, private readonly ResolverFactoryInterface $itemMutationResolverFactory, private readonly ResolverFactoryInterface $itemSubscriptionResolverFactory, private readonly ContainerInterface $filterLocator, private readonly Pagination $pagination, private readonly ?NameConverterInterface $nameConverter, private readonly string $nestingSeparator) | ||
| public function __construct(private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, private readonly PropertyMetadataFactoryInterface $propertyMetadataFactory, private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, private readonly DynamicResourceExtractorInterface $dynamicResourceExtractor, private readonly ResourceClassResolverInterface $resourceClassResolver, private readonly TypesContainerInterface $typesContainer, private readonly TypeBuilderInterface $typeBuilder, private readonly TypeConverterInterface $typeConverter, private readonly ResolverFactoryInterface $itemResolverFactory, private readonly ResolverFactoryInterface $collectionResolverFactory, private readonly ResolverFactoryInterface $itemMutationResolverFactory, private readonly ResolverFactoryInterface $itemSubscriptionResolverFactory, private readonly ContainerInterface $filterLocator, private readonly Pagination $pagination, private readonly ?NameConverterInterface $nameConverter, private readonly string $nestingSeparator) |
| * {@inheritdoc} | ||
| */ | ||
| public function getResourcePaginatedCollectionType(GraphQLType $resourceType, string $resourceClass, Operation $operation): GraphQLType | ||
| public function getResourcePaginatedCollectionType(GraphQLType $resourceType, Operation $operation): GraphQLType |
| * Gets the type of a paginated collection of the given resource type. | ||
| */ | ||
| public function getResourcePaginatedCollectionType(GraphQLType $resourceType, string $resourceClass, Operation $operation): GraphQLType; | ||
| public function getResourcePaginatedCollectionType(GraphQLType $resourceType, Operation $operation): GraphQLType; |
There was a problem hiding this comment.
We can't change an interface like this right?
| $dynamicResourceName = $this->getDynamicResourceName($resourceClass); | ||
|
|
||
| $this->dynamicResources[$dynamicResourceName] = [ | ||
| array_merge(['class' => $resourceClass], $config), |
There was a problem hiding this comment.
array_merge is quite slow for this we could just add the class to the config right?
There was a problem hiding this comment.
I think it doesn't impact performance but we can.
| * | ||
| * @author Alan Poulain <contact@alanpoulain.eu> | ||
| */ | ||
| interface DynamicResourceExtractorInterface extends ResourceExtractorInterface |
There was a problem hiding this comment.
do we really need to add a new interface? its wanted that a ResourceExtractorInterface doesn't have an addResource we're using a Factory to prepare resources inside it no?
There was a problem hiding this comment.
We need an interface since this method needs to be called from the fields builder.
| public function isDynamic(): bool | ||
| { | ||
| return str_starts_with($this->resourceClass, self::DYNAMIC_RESOURCE_CLASS_PREFIX); | ||
| } |
There was a problem hiding this comment.
I really don't like this graphql-specific code here, can you explain this?
There was a problem hiding this comment.
This is not GraphQL-specific. The aim is to create metadata for a resource which doesn't exist.
|
|
||
| public function isDynamic(): bool | ||
| { | ||
| return str_starts_with($this->resourceClass, self::DYNAMIC_RESOURCE_CLASS_PREFIX); |
There was a problem hiding this comment.
imo resourceClass should be a class-string this breaks it.
There was a problem hiding this comment.
Sure but we need a way to distinguish a dynamic resource for a normal one.
* fix: update yaml extractor test file coding standard (#5068) * fix(graphql): add clearer error message when TwigBundle is disabled but graphQL clients are enabled (#5064) * fix(metadata): add class key in payload argument resolver (#5067) * fix: add class key in payload argument resolver * add null if everything else goes wrong * fix: upgrade command remove ApiSubresource attribute (#5049) Fixes #5038 * fix(doctrine): use abitrary index instead of value (#5079) * fix: uri template should respect rfc 6570 (#5080) * fix: remove @internal annotation for Operations (#5089) See #5084 * fix(metadata): define a name on a single operation (#5090) fixes #5082 * fix(metadata): deprecate when user decorates in legacy mode (#5091) fixes #5078 * fix(graphql): use right nested operation (#5102) * Revert "fix(graphql): use right nested operation (#5102)" (#5111) This reverts commit 44337dd. * fix(graphql): always allow to query nested resources (#5112) * fix(graphql): always allow to query nested resources * review Co-authored-by: Alan Poulain <contact@alanpoulain.eu> * chore: php-cs-fixer update * fix: only alias if exists for opcache preload Fixes api-platform/api-platform#2284 (#5110) Co-authored-by: Liviu Mirea <liviu.mirea@wecodepixels.com> * chore: php-cs-fixer update (#5118) * chore: php-cs-fixer update * chore: php-cs-fixer update * fix(metadata): upgrade script keep operation name (#5109) origin: #5105 Co-authored-by: WilliamPeralta <william.peralta18@gmail.com> * chore: v2.7.3 changelog * chore: v3.0.3 changelog Co-authored-by: helyakin <CourcierMarvin@gmail.com> Co-authored-by: ArnoudThibaut <thibaut.arnoud@gmail.com> Co-authored-by: davy-beauzil <38990335+davy-beauzil@users.noreply.github.com> Co-authored-by: Baptiste Leduc <baptiste.leduc@gmail.com> Co-authored-by: Xavier Laviron <norival@users.noreply.github.com> Co-authored-by: Alan Poulain <contact@alanpoulain.eu> Co-authored-by: Liviu Cristian Mirea-Ghiban <contact@liviucmg.com> Co-authored-by: Liviu Mirea <liviu.mirea@wecodepixels.com> Co-authored-by: WilliamPeralta <william.peralta18@gmail.com>
See #4613 (comment).
Supersedes #4930.
Fixes #8056.
The principal issue was mainly because the root operation was used instead of the nested resource one.
This PR also improves how GraphQL handles a nested resource when the query operation does not exist.
Instead of having a fallback on the REST operation (and an exception if it does not exist), it creates a "dynamic" resource having the default operations.
This dynamic resource is created using a new
DynamicExtractorwith anaddResourcemethod, which can take an optional configuration array.In the future, I think this could be useful to control how a nested resource is handled by GraphQL (for instance by using the
ApiPropertyattribute).