api-platform / core

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

Add ErrorResource Schemes to OpenAPI documentation #6003

Open f1amy opened 7 months ago

f1amy commented 7 months ago

Description
Currently, we have a way to document error HTTP status codes supported by an Operation with exceptionToStatus property, as well as adding our own documentation with openApi property. That much is great, however by default we have limited information about errors in the OpenAPI documentation: an HTTP code, description and "string" as scheme.

With v3.2, we can now represent errors/exceptions as ErrorResource, which should give us the ability to show proper scheme of a response in documentation.

For that we need to have a way to map ErrorResources to specific Operations. Knowing what ErrorResources could be thrown, we can turn ErrorResource classes into OpenAPI documentation.

Example
A way to solve this would be by introducing to Operation class a new property errors, that contains a list of ErrorResources used:

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;

#[ApiResource(
    operations: [
        new Get(
            uriTemplate: '/orders/{id}',
            errors: [
                OrderNotFoundError::class,
            ],
        ),
    ],
)]
class Order {}
use ApiPlatform\Metadata\ErrorResource;
use ApiPlatform\Metadata\Exception\ProblemExceptionInterface;

#[ErrorResource(status: 404)]
class OrderNotFoundException extends \Exception implements ProblemExceptionInterface
{
    // ...
}
GeLoLabs commented 3 months ago

I would also like to see something like this but IMHO, it should be nice to also handle generic ErrorResource (with no status code explicitely configured) such as:

#[ErrorResource]
class Problem extends \Exception
{
    // ...
}

then use it with:

#[ApiResource(
    operations: [
        new Get(
            uriTemplate: '/orders/{id}',
            errors: [
                401 => Problem::class,
                403 => Problem::class,
                404 => Problem::class,
            ],
        ),
    ],
)]
class Order {}