api-platform / core

The server component of API Platform: hypermedia and GraphQL APIs in minutes
https://api-platform.com
MIT License
2.45k stars 882 forks source link

DTO class requires be ApiResource #2768

Closed CvekCoding closed 3 years ago

CvekCoding commented 5 years ago

Hello. I noticed, that if I use DTO feature and DTO-object is not an ApiResource, then here I have exception: https://github.com/api-platform/core/blob/df7087816254085741820cd1513aeb5fdaaf13a1/src/Bridge/Doctrine/Orm/Extension/EagerLoadingExtension.php#L289

What if we wrap this line like this?

        try {
            $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
        } catch (ResourceClassNotFoundException $e) {
            return [];
        }
soyuka commented 5 years ago

Yes it would be good to fix this (not sure about the return value though), could you open a PR? Thanks!

teohhanhui commented 5 years ago

This whole DTO thing is messed up. :laughing:

I don't think that's the right fix. We should get the resource class from the input class.

CvekCoding commented 5 years ago

@teohhanhui BTW you are right - DTO is not working, at least for GraphQl. When I investigated the reasons, I found the following: I see only one place where DataTransformerInterface class used: https://github.com/api-platform/core/blob/0888bf33429a37d031345bf7c720f23010a50de4/src/Serializer/AbstractItemNormalizer.php#L172-L187 To be invoked, AbstractItemNormalizer::supportDenormalization() must return true, which is possible only for ApiResource class. But if DTO is not ApiResource (which is desirable) no transformer will ever be called for Input DTO.

To fix this for me I did the hotfix here: https://github.com/api-platform/core/blob/0888bf33429a37d031345bf7c720f23010a50de4/src/GraphQl/Resolver/Factory/ItemMutationResolverFactory.php#L127

by removing priority for inputClass:

$item = $this->normalizer->denormalize($args['input'], $resourceClass, ItemNormalizer::FORMAT, $context);

I understand that this is not the real fix, but it works for me and DTO works perfect for me now. I wrote this to give you signal that DTO is broken.

davidgerth commented 5 years ago

Would love to see this, too. I am currently mapping a flat MySQL structure to DTOs containing non-resource subelements. This is breaking the GraphQL part.

teohhanhui commented 5 years ago

@Siregacvek No, the ItemNormalizer is not used for input/output classes. See ObjectNormalizer in API Platform (we decorate ObjectNornalizer from Symfony).

teohhanhui commented 5 years ago

Is this still an issue with the latest 2.4 branch (use 2.4.x-dev in composer.json)? If yes, could you help us add a failing Behat test?

As a workaround, you can disable eager loading on the affected operation for now.

soyuka commented 3 years ago

Greetings! We appreciate your concern but weren't able to reproduce this issue or it is more of a question. As described in the API Platform contributing guide, we use GitHub issues for bugs and feature requests only.

For support question ("How To", usage advice, or troubleshooting your own code), you have several options:

Feel free reach one of the support channels above. In the meantime we're closing this issue.