Skip to content

OpenApi class Refference is not generated correctly $ref #8143

Description

@Mixno09

API Platform version(s) affected: 4.0.16
Laravel version 11.38.2

Description
OpenApi class Refference is not generated correctly $ref

How to reproduce
Create you response component

<?php

declare(strict_types=1);

namespace Modules\Common\OpenApi;

use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
use ApiPlatform\OpenApi\Model\MediaType;
use ApiPlatform\OpenApi\Model\Response;
use ApiPlatform\OpenApi\OpenApi;
use ArrayObject;

final readonly class OpenApiFactory implements OpenApiFactoryInterface
{
    public function __construct(
        private OpenApiFactoryInterface $decorated
    ) {}

    public function __invoke(array $context = []): OpenApi
    {
         $openApi = ($this->decorated)($context);

        $responseSchemas = $openApi->getComponents()->getResponses();
        $responseSchemas['401'] = $this->getNotAuthenticationResponseSchema();
        
        return $openApi;
    }

    private function getNotAuthenticationResponseSchema(): Response
    {
        return new Response(
            description: 'Not Authentication',
            content: new ArrayObject([
                'application/json' => new MediaType(
                    schema: new ArrayObject([
                        'type' => 'object',
                        'properties' => [
                            'type' => ['type' => 'string', 'example' => '/errors/401'],
                            'title' => ['type' => 'string', 'example' => 'An error occurred'],
                            'status' => ['type' => 'integer', 'example' => 401],
                            'detail' => ['type' => 'string', 'example' => 'Unauthenticated'],
                        ],
                    ])
                ),
            ]),
        );
    }
}

Provide a link to this response in your resource

<?php

declare(strict_types=1);

namespace App\Resources;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\OpenApi\Model\Reference;

#[ApiResource(
    operations: [
        new Post(
            openapi: new Operation(
                responses: [
                    401 => new Reference(ref: '#/components/responses/401'),
                ],
                summary: '',
                description: '',
             ),
        ),
    ],
)]
final class Resource
{
}

The link in the response is serialized without $

"responses": {
      "201": {
          "description": "Resource created",
          "content": {
              "application/json": {
                  "schema": {
                      "$ref": "#/components/schemas/Output"
                  }
              },
       },
       "401": {
           "ref": "#/components/responses/401"
       }
}

Possible Solution
In ApiPlatform\Laravel\ApiPlatformProvider when creating ObjectNormalizer::class add name converter

$this->app->singleton(ObjectNormalizer::class, function (Application $app) {
            $config = $app['config'];
            $defaultContext = $config->get('api-platform.serializer', []);

            $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
            $nameConverter = new MetadataAwareNameConverter($classMetadataFactory);
            return new ObjectNormalizer(
                classMetadataFactory: $classMetadataFactory, 
                nameConverter: $nameConverter, 
                defaultContext: $defaultContext,
            );
});

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions