Le blog

Sortie d'API Platform 4.1 : la documentation au cœur de la découvrabilité des API

Publié le 04 mars 2025

Nous sommes ravis de vous annoncer la disponibilité immédiate de la version 4.1 d'API Platform ! API Platform est un framework centré sur les standards des API, aidant les développeurs et développeuses à les maintenir et à les exploiter. Avec API Platform 4.1, nous mettons l’accent sur l’amélioration de la prise en charge des spécifications Hydra, OpenAPI et JSON Schema. Découvrons dans cet article ces différentes évolutions. Ce billet est aussi disponible dans sa langue d'origine ici.

API Platform 4.1" class="wp-image-10895"/><figcaption class="wp-element-caption#

Améliorations d’OpenAPI

#
Créer plusieurs versions d'une spécification

Il est désormais possible de décliner une même spécification OpenAPI en plusieurs versions en utilisant le tag x-apiplatform-tags :

use ApiPlatform\OpenApi\Factory\OpenApiFactory;

#[GetCollection(openapi: new Operation(extensionProperties: [OpenApiFactory::API_PLATFORM_TAG => ['customer', 'developer']]))]
#[Post(openapi: new Operation(extensionProperties: [OpenApiFactory::API_PLATFORM_TAG => 'developer']))]
class Book {}

Ensuite, utilisez soit le paramètre de requête pour la version web, comme /docs?filter_tags[]=customer, soit via la ligne de commande :

bin/console api:openapi:export --filter-tags=customer

Cela produira une spécification incluant uniquement les opérations correspondant à votre tag.

#
Schémas d'erreur

Avec l'amélioration de notre implémentation de la spécification Problem Detail dans la version 4.0 et la possibilité de déclarer des erreurs comme des ressources API, nous avons franchi un pas de plus vers la possibilité de documenter leur schéma JSON. Depuis la version 3.4, il était déjà possible d’ajouter des erreurs à la documentation d’une opération.

#[GetCollection(errors: [MyDomainException::class])]
class Greeting
{
// ...
}

Cela est maintenant également activé pour toutes les réponses standard que nous supportons. Par exemple, une erreur 422 (Unprocessable entity) est désormais documentée dans tous les formats supportés :

capture d'écran d'une erreur 402" class="wp-image-10891

Le schéma JSON associé à une erreur est également disponible avec une documentation plus agréable :

capture d'écran d'une erreur 400" class="wp-image-10892#

Hydra

Le patch Hydra modifie le hydra:title par défaut et utilise la ressource shortname. Auparavant, l'information hydra:title dupliquait celle de hydra:description. Le rdfs:label a été supprimé de la hydra:Class, car il était utilisé à la place de hydra:title. Sur hydra:property, rdfs:label a été renommé en label, car le namespace rdfs est désormais disponible dans le contexte.

Les classes ApiPlatform\Metadata\ErrorResource et ConstraintViolation (de la classe ValidationException) sont maintenant générées directement à partir de vos classes PHP. Seule la ConstraintViolationList est définie en dur et documente la propriété ConstraintViolation::violation. Par conséquent, vos propres ressources d'erreur sont également documentées. De plus, nous avons maintenant défini rdfs:subClassOf sur hydra:Error.

Il est possible de masquer une opération Hydra (avec #[Get(hideHydraOperation: true)]), et de sauter une propriété documentée en utilisant #[ApiProperty(hydra: false)] sur une classe.

Sur les opérations d'écriture, nous avons ajouté le champ expectsHeader.

#

Paramètres de requête et filtrage

Vous pouvez désormais configurer API Platform pour qu'il envoie une erreur de validation lorsqu'un paramètre de requête est utilisé sur votre API alors qu'il n'est pas pris en charge. Pour cela, activez strictQueryParameters: true (globalement via les paramètres par défaut, ou au niveau d’une ressource ou d’une opération). En plus de cela, Vincent Amstoutz et moi-même avons travaillé sur l'amélioration de la déclaration des filtres Symfony au sein des paramètres de requête.

#[GetCollection(
    parameters: [
        'enabled' => new QueryParameter(
            filter: new BooleanFilter(),
            property: 'active',
        ),
    ],
)]
#[ORM\Entity]
class FilteredBooleanParameter
{
}

Auparavant, un filtre devait être un service Symfony ; désormais, c'est une instance statique. Un filtre est un callback où vous devez avoir tout ce qui est nécessaire pour effectuer le filtrage :

public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void;

Par conséquent, vous ne devriez pas avoir besoin d'injection de dépendances. Nous ne prévoyons pas de déprécier l'utilisation d'un service, mais nous estimons que cette approche est plus conviviale et qu'elle améliore également le découplage de la documentation d'un paramètre. Pour cela, vous disposez de deux nouvelles interfaces : ApiPlatform\Metadata\JsonSchemaFilterInterface et ApiPlatform\Metadata\OpenApiParameterFilterInterface

use ApiPlatform\Metadata\OpenApiParameterFilterInterface;
use ApiPlatform\Metadata\JsonSchemaFilterInterface;

public class MyDateFilter implements JsonSchemaFilterInterface, OpenApiParameterFilterInterface
    /**
     * @return array<string, string>
     */
    public function getSchema(Parameter $parameter): array
    {
        return ['type' => 'date'];
    }

    public function getOpenApiParameters(Parameter $parameter): OpenApiParameter|array|null
    {
        $in = $parameter instanceof QueryParameter ? 'query' : 'header';
        $key = $parameter->getKey();

        return [
            new OpenApiParameter(name: $key.'[after]', in: $in),
            new OpenApiParameter(name: $key.'[before]', in: $in),
            new OpenApiParameter(name: $key.'[strictly_after]', in: $in),
            new OpenApiParameter(name: $key.'[strictly_before]', in: $in),
        ];
    }

Le paramètre OpenAPI utilisera le getSchema si aucun schéma n'est fourni. Cela offre plus de contrôle sur un filtre sans avoir à copier ce filtre simplement pour modifier une partie de la documentation.

#

Laravel

Avec la prise en charge de Laravel 12 (^4.0.19), un BooleanFilter a été ajouté, et nous enregistrons automatiquement la Policy du modèle lorsqu'elle est trouvée. Nous avons amélioré la prise en charge générale d'Eloquent. Le cache par défaut de nos Métadonnées a été défini sur le cache de fichiers, car il est plus approprié que d'utiliser le cache global (vous pouvez toujours changer cela). Un grand merci à toitzi et amermchaudhary pour avoir fourni de nombreuses corrections depuis la sortie du support de Laravel en septembre dernier !

#

Et bien plus encore

Jérôme Tamarelle de chez MongoDB a amélioré l'utilisation générale de la mémoire de notre provider de collections MongoDB ! Elasticsearch 7 est de nouveau pris en charge, nous pouvons configurer la profondeur maximale des requêtes GraphQL et la complexité maximale des requêtes, et bien plus encore ! Découvrez le détail de cette release directement sur GitHub, et merci encore à chaque contributeur !

#

Et les prochaines releases ?

Nous travaillons sur l'ajout de nouveaux filtres et la refactorisation de notre SearchFilter. Nous nous concentrerons également sur la génération de schémas JSON, car ils sont encore loin d'être parfaits, notamment parce que nous avons étudié une belle optimisation où nous mutualisons les schémas avec des schémas de base par format : jetez un coup d'œil ici. En parallèle, nous travaillons sur un client HTTP Hypermedia qui est encore en phase d'expérimentation.

Toujours concernant API Platform, il reste désormais moins de vingt jours pour soumettre un sujet à notre CFP ! Rendez-vous sur la page de l'événement pour découvrir les différentes thématiques attendues, et rendez-vous courant mai pour découvrir la programmation de cette édition qui marquera les 10 ans du framework.

Antoine Bluchet

Antoine Bluchet

Principal developer

Mots-clésAPI Platform, Release

Le blog

Pour aller plus loin