LinksHandler throwing: The class "\App\Entity\xxx" cannot be retrieved from "\App\ApiResource\xxx". When using stateOptions with stateOption entityClass and Collections - GraphQL Query #6590
Description
When converting from Entity ApiResource to DTOs with ApiResource and querying an API Resource which contains a OneToMany Relationship, an error is thrown by the LinksHandlerTrait which states:
The class "\App\Entity\xxx" cannot be retrieved from "\App\ApiResource\xxx" which is unexpected, as the Entity should not be retrieved from the DTO Class.
Note: This works fine using the Entity ApiResource.
Comparing the Processed Data inside the File: api/vendor/api-platform/core/src/Doctrine/Common/State/LinksHandlerTrait.php at Line 80 - 85 i could see, that the Handler is fed with resourceClass \App\Entity\xxx which is compared to \Api\Resource\xxx and obviously fails. Debugging the same Data when defining the API Resource above an Entity i could see, that \App\Entity\xxx was compared against \App\Entity\xxx which does obviously work.
Create an API Platform Project, add GraphQL Dependency (webonyx/graphql-php)
Create 2 Entities and reference them One to Many
Create 2 API Resources with stateOptions referring to the Entity ( example below )
Run Query on the Resource which should contain the Array of the referenced Resources
{
serverApiResources {
edges {
node {
name
ips {
edges {
node {
ip
public
}
}
}
}
}
}
}
Example API Resources:
#[ApiResource(
graphQlOperations: [
new Query(),
new QueryCollection()
],
provider: EntityClassDtoStateProvider::class,
processor: EntityClassDtoStateProcessor::class,
stateOptions: new Options(entityClass: ServerEntity::class),
)]
class ServerApiResource
{
#[ApiProperty(readable: false, writable: false, identifier: true)]
public ?int $id = null;
public string $name;
/**
* @var IpApiResource[]
*/
public array $ips = [];
public function addIp(IpApiResource $ip): void
{
$this->ips[] = $ip;
}
public function removeIp(IpApiResource $ip): void
{
unset($this->ips[array_search($ip, $this->ips)]);
}
}
#[ApiResource(
graphQlOperations: [
new Query(),
new QueryCollection()
],
provider: EntityClassDtoStateProvider::class,
processor: EntityClassDtoStateProcessor::class,
stateOptions: new Options(entityClass: IpEntity::class),
)]
class IpApiResource
{
#[ApiProperty(readable: true, writable: false, identifier: true)]
public ?int $id = null;
public string $ip;
public bool $public;
}
Possible Solution
I've looked into the LinksHandlerTrait File (api/vendor/api-platform/core/src/Doctrine/Common/State/LinksHandlerTrait.php), it seems that we could replace the $resourceClass ( which seems to be populated with the Entity Class ) with $context['resource_class']. If we do that, the query works just fine, but so far i have not checked any side effects regarding mutations etc.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
API Platform version(s) affected: 3.3.12
Description
When converting from Entity ApiResource to DTOs with ApiResource and querying an API Resource which contains a OneToMany Relationship, an error is thrown by the LinksHandlerTrait which states:
The class "\App\Entity\xxx" cannot be retrieved from "\App\ApiResource\xxx"
which is unexpected, as the Entity should not be retrieved from the DTO Class. Note: This works fine using the Entity ApiResource.Comparing the Processed Data inside the File:
api/vendor/api-platform/core/src/Doctrine/Common/State/LinksHandlerTrait.php
at Line 80 - 85 i could see, that the Handler is fed with resourceClass\App\Entity\xxx
which is compared to\Api\Resource\xxx
and obviously fails. Debugging the same Data when defining the API Resource above an Entity i could see, that\App\Entity\xxx
was compared against\App\Entity\xxx
which does obviously work.How to reproduce
See my example Repository: https://github.com/KaiGrassnick/api-platform3-graphql-one-to-many-issue
Otherwise:
webonyx/graphql-php
)stateOptions
referring to the Entity ( example below )Example API Resources:
Possible Solution I've looked into the LinksHandlerTrait File (
api/vendor/api-platform/core/src/Doctrine/Common/State/LinksHandlerTrait.php
), it seems that we could replace the$resourceClass
( which seems to be populated with the Entity Class ) with$context['resource_class']
. If we do that, the query works just fine, but so far i have not checked any side effects regarding mutations etc.Additional Context
Error Output: