Skip to content

Unable to generate IRI when using non-resource DTO as response #3090

Description

@jorissteyn

We're still running v2.4.0-beta.2 and have a problem upgrading to v2.4.0 or higher.

I'm using a custom operation on an entity:

...

 *       "entity_custom_op"={
 *         "method"="POST",
 *         "path"="/entity/custom-op",
 *         "controller"=MyController::class,
 *         "defaults"={"_api_persist"=false},
 *         "output"=MyDto::class,
 *         "normalization_context"={"default"}
 *       }
...

This works fine in v2.4.0-beta.2: we post an entity to the endpoint, our transformer performs some logic and returns a DTO, the DTO gets serialized and is returned as response.

Upgrading to any version above v2.4.0-beta.2 results in API platform trying to generate an IRI for the entity:

Uncaught PHP Exception ApiPlatform\Core\Exception\InvalidArgumentException: 
"Unable to generate an IRI for the item of type "MyEntity"" at vendor/api-platform/core/src/Bridge/Symfony/Routing/IriConverter.php line 133 {"exception":"[object] (ApiPlatform\\Core\\Exception\\InvalidArgumentException(code: 0): Unable to generate an IRI for the item of type \"MyEntity\" at /vendor/api-platform/core/src/Bridge/Symfony/Routing/IriConverter.php:133, Symfony\\Component\\Routing\\Exception\\InvalidParameterException(code: 0): Parameter \"id\" for route \"api_my_entity\" must match \"[^/\\.]++\" (\"\" given) to generate a corresponding URL. at /vendor/symfony/routing/Generator/UrlGenerator.php:181)"} []

I'm unable to figure out the culprit, is this a bug in all versions of API platform above 2.4.0-beta2 or has something changed in the way non-resource responses should be implemented?

Following is a stack trace of the exception:

#0 /vendor/symfony/routing/Generator/CompiledUrlGenerator.php(56): Symfony\Component\Routing\Generator\UrlGenerator->doGenerate(Array, Array, Array, Array, Array, 'api_purchase_or...', 1, Array, Array)
#1 /vendor/symfony/routing/Router.php(254): Symfony\Component\Routing\Generator\CompiledUrlGenerator->generate('api_purchase_or...', Array, 1)
#2 /vendor/api-platform/core/src/Bridge/Symfony/Routing/Router.php(101): Symfony\Component\Routing\Router->generate('api_purchase_or...', Array, 1)
#3 /vendor/api-platform/core/src/Bridge/Symfony/Routing/IriConverter.php(126): ApiPlatform\Core\Bridge\Symfony\Routing\Router->generate('api_purchase_or...', Array, 1)
#4 /vendor/api-platform/core/src/JsonLd/Serializer/ObjectNormalizer.php(87): ApiPlatform\Core\Bridge\Symfony\Routing\IriConverter->getIriFromItem(Object(MyEntity))
#5 /vendor/symfony/serializer/Serializer.php(152): ApiPlatform\Core\JsonLd\Serializer\ObjectNormalizer->normalize(Object(MyDto), 'jsonld', Array)
#6 /vendor/api-platform/core/src/Serializer/AbstractItemNormalizer.php(125): Symfony\Component\Serializer\Serializer->normalize(Object(MyDto), 'jsonld', Array)
#7 /vendor/api-platform/core/src/JsonLd/Serializer/ItemNormalizer.php(69): ApiPlatform\Core\Serializer\AbstractItemNormalizer->normalize(Object(MyEntity), 'jsonld', Array)
#8 /vendor/symfony/serializer/Serializer.php(152): ApiPlatform\Core\JsonLd\Serializer\ItemNormalizer->normalize(Object(MyEntity), 'jsonld', Array)
#9 /vendor/symfony/serializer/Serializer.php(125): Symfony\Component\Serializer\Serializer->normalize(Object(MyEntity), 'jsonld', Array)
#10 /vendor/api-platform/core/src/EventListener/SerializeListener.php(95): Symfony\Component\Serializer\Serializer->serialize(Object(MyEntity), 'jsonld', Array)
#11 /vendor/symfony/event-dispatcher/Debug/WrappedListener.php(126): ApiPlatform\Core\EventListener\SerializeListener->onKernelView(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view', Object(Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher))
#12 /vendor/symfony/event-dispatcher/EventDispatcher.php(258): Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view', Object(Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher))
#13 /vendor/symfony/event-dispatcher/EventDispatcher.php(233): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, 'kernel.view', Object(Symfony\Component\HttpKernel\Event\ViewEvent))
#14 /vendor/symfony/event-dispatcher/EventDispatcher.php(73): Symfony\Component\EventDispatcher\EventDispatcher->callListeners(Array, 'kernel.view', Object(Symfony\Component\HttpKernel\Event\ViewEvent))
#15 /vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php(168): Symfony\Component\EventDispatcher\EventDispatcher->dispatch(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view')
#16 /vendor/symfony/http-kernel/HttpKernel.php(156): Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view')
#17 /vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#18 /vendor/symfony/http-kernel/Kernel.php(198): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /public/index.php(27): Symfony\Component\HttpKernel\Kernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#20 {main}

Seems related to #2910 and #2860

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions