core: [Swagger] Undefined array key "$ref" since 3.1.6

API Platform version(s) affected: 3.1.6

Description

Since this new version, it is impossible to acces my swagger documentation via /api

For instance for a simple entrypoint like this one

new Metadata\GetCollection(
    routeName: 'api_get_user',
    openapi: new Model\Operation(
        responses: [
            Response::HTTP_UNAUTHORIZED => new Model\Response(ResponseMessage::UNAUTHORIZED),
        ],
        parameters: [
            new Model\Parameter(
                name: 'id',
                in: 'query',
                description: 'The User identifier',
                schema: ['type' => 'object'],
                style: 'deepObject',
                explode: true,
            ),
            new Model\Parameter(
                name: 'name|lastname|username',
                in: 'query',
                description: 'The User denomination',
                schema: ['type' => 'object'],
                style: 'deepObject',
                explode: true,
            ),
        ],
    ),
),

causes a 500 error

Capture d’écran 2023-03-27 à 18 12 04

Additional Context

I’m working on MacOs, Php 8.1, Symfony 6.2.7, doctrine-bundle 2.9. Everything is working fine on 3.1.5

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 8
  • Comments: 19 (7 by maintainers)

Commits related to this issue

Most upvoted comments

expect a release in the hour

I’ve a reproducer thanks to @paullallier, trying to release a patch by the end of the day!

@soyuka: I’m virtually certain it’s that patch, but I’m in the middle of a code change and can’t easier test it (I don’t trust my git shelve changes skills…), but I checked before and I had the problem with 3.1.6 and not when I rolled back to 3.1.5.

I suspect it’s not the way that most people triggered the issue, but I was doing this: https://github.com/api-platform/docs/issues/1697

If you replace the ApiResource attribute on any Entity with #[ApiResource(operations: [])] and reload the swagger UI, you should see the bug.

I suspect declaring an Entity with only GetCollection operations would also show it - and be more realistic.

A simple resource having #[ApiResource(operations: [])] is NOT enought for the bug to appear.

Odd. It definitely triggers it for me, but maybe we have something else different in our setups. Your example is definitely a more realistic one though.

Is there a better way removing operations? I am using some API resources as a subresource without any operations.

@DeLm0re / @soyuka - the above is my case as well, I had to temporary modify the code to return:

return ['$ref' => $subSchema['$ref'] ?? '']; 

Only to be able to continue with my daily development tasks.

@soyuka After some digging & xdebug, it seems that the error occurs here

https://github.com/api-platform/core/blob/ccef472cade42b189fa8cb7793e27fad1349e289/src/JsonSchema/TypeFactory.php#L146-L157

Because $subSchema is not an array at the return point but a ApiPlatform\JsonSchema\Schema (a PHP \ArrayObject) or at least the code can not access the index $ref

I would suggest something like this instead

return ['$ref' => $subSchema->offsetExists('$ref') ? $subSchema->offsetGet('$ref') : null];

I can confirm downgrading to 3.1.5 (PHP 8.1.11, Symfony 6.2.7) fix the problem.

Same problem here. This happens only for some schemas as far as I can tell, they are created in L155 of the TypeFactory

$subSchema = $this->schemaFactory->buildSchema($className, $format, Schema::TYPE_OUTPUT, null, $subSchema, $serializerContext, false);

without the $ref: https://i.imgur.com/0xVVun6.png

Maybe related to Resources that have no (exposed) endpoints and thus no definition (yet)? E.g. it happens for me with embeded Images that are annotated with:

#[ApiResource(
    types: 'https://schema.org/MediaObject',
    operations: [
        new NotExposed(),
    ],
)]

Also: I’m very suprised about the introduced BC break with that patch version: ApiPlatform\OpenApi\Factory\OpenApiFactory::OPENAPI_DEFINITION_NAME no longer exists (but is moved to the SchemaFactory) and causes runtime errors in my code. Shouldn’t this be marked deprecated until the next major and refer to the SchemaFactory::OPENAPI_DEFINITION_NAME for the time being? I use this constant in my custom ResourceMetadataCollectionFactory wrapper, and it was not marked “internal” before (and is not now) .

Hi, same problem since 3.1.6 with PHP 8.2.4 and Symfony 6.2.7.

I get the same error on a decorated service, i.e:

final readonly class JwtDecorator implements OpenApiFactoryInterface
{
    public function __construct(
        private OpenApiFactoryInterface $decorated,
        private UrlGeneratorInterface $router
    ) {
    }

    public function __invoke(array $context = []): OpenApi
    {
        $openApi = ($this->decorated)($context); // <- This triggers the error.
    ...