Sortie d’API Platform 4.4 et 5.0
Publié le 1 octobre 2026
Les versions 4.4 et 5.0 d’API Platform ont été publiées en direct il y a quelques jours lors de l’API Platform Conference 2026 à Lille, à l’occasion du talk d’Antoine Bluchet « Are APIs still relevant in the AI era? » (dont vous pouvez retrouver les slides en ligne). La version originale de cet article, écrit en anglais, est aussi disponible.
L’année a été particulièrement intense sur api-platform/core : entre début janvier et le 13 septembre, 508 pull requests ont été ouvertes et 429 mergées, soit +76 % d’ouvertures et +77 % de merges par rapport à 2025. Rien que depuis la v4.3.0, ce sont 468 commits qui ont été intégrés. Si l’écriture du code s’est accélérée pour tout le monde avec l’essor de l’intelligence artificielle, la revue de code demande toujours autant de rigueur : nos exigences en matière de justesse, de rétrocompatibilité et de maintenabilité restent strictement inchangées. Un grand merci à toutes les personnes qui ont contribué !

Are APIs still relevant in the AI era?
La réponse est oui. L’interface évolue, mais l’API reste la clé de voûte.
La première partie du talk d’Antoine proposait une démo de Mon parc auto, une application de gestion de garage où un agent IA dialogue avec un backend API Platform via le protocole MCP : recherche d’immatriculation, pièces compatibles via TecDoc, préconisations de fluides et historique d’entretien. La même annotation #[ApiResource] sert simultanément une collection HTTP classique et un outil MCP : le DTO d’entrée est automatiquement converti en JSON Schema pour l’outil, tandis que les règles métier, les permissions et les données restent exactement là où elles ont toujours été.
Il existe trois méthodes pour exposer une API existante à un agent :
- OpenAPI : expose les opérations HTTP en créant un outil par opération. Sur l’API de démo d’Antoine,
@ivotoby/openapi-mcp-servera généré 57 outils pour un total de 10 018 tokens de contexte. L’agent paie cette facture en tokens à chaque échange. - Une passerelle Hypermédia : la découverte démarre dès l’index. Les outils sont chargés à mesure que l’agent navigue, grâce aux
@contextet/docs.jsonldqui décrivent les types et opérations, ainsi qu’ànotifications/tools/list_changedqui signale au client qu’il faut rafraîchir. C’est l’approche decoopTilleuls/hydra-mcp-bridge, dont la réflexion est détaillée dans le papier de recherche rédigé dernièrement par Antoine et Kévin. - Des outils sur-mesure (Manual tools) : via
new McpTool(description: ..., input: ..., processor: ...). On définit un outil par tâche métier au lieu d’un outil par opération, complété par un prompt guidant l’agent sur la façon de les chaîner. C’est plus de travail, mais les résultats sont supérieurs en terme de performance.
Note : le mécanisme list_changed requiert un canal SSE persistant, alors que PHP n’est pas taillé nativement pour les connexions longue durée. FrankenPHP intégrant Mercure, le protocole MCP SSE peut s’exécuter directement à travers lui. Un prototype est disponible : vos retours sont les bienvenus !
Disponible en 4.4 : migration de vos filtres
C’est le gros morceau de cette version. Les filtres historiques déclarés via #[ApiFilter] sont dépréciés en 4.4 et leur suppression définitive est fixée pour la v6.0 :
// Deprecated in 4.4
#[ApiFilter(SearchFilter::class, properties: ['name' => 'partial'])]
Désormais, la logique repose sur le principe un paramètre, un filtre :
#[ApiResource(parameters: [
'name' => new QueryParameter(filter: new PartialSearchFilter()),
])]
Un appel ?name=api exécutera la clause WHERE name LIKE %api%. Inutile de tout réécrire à la main, nous avons prévu un outil de migration automatique :
php bin/console api:upgrade-filter
Nouveaux filtres de recherche (Doctrine ORM & MongoDB ODM) :
StartSearchFilter (title LIKE 'api%')EndSearchFilter (title LIKE '%platform')WordStartSearchFilter (title LIKE 'api%' OR title LIKE '% api%')
Composition de filtres : ComparisonFilter vient enrober un autre filtre pour lui ajouter des opérateurs :
new QueryParameter(
property: 'quantity',
filter: new ComparisonFilter(new ExactFilter()),
)
L’exemple précédent gère nativement ?quantity[gte]=10 et ?quantity[lt]=20.
Les filtres OrFilter et FreeTextQueryFilter permettent de mapper un paramètre unique vers plusieurs propriétés :
'q' => new QueryParameter(
filter: new FreeTextQueryFilter([
'title' => new OrFilter(new PartialSearchFilter()),
'isbn' => new OrFilter(new ExactFilter()),
]),
)
Avec l’exemple précédent, ?q=978 générera la requête WHERE LOWER(title) LIKE '%978%' OR isbn = '978'.
Enfin, ChainFilter applique plusieurs filtres sur un même paramètre :
'code' => new QueryParameter(
filter: new ChainFilter([new StartSearchFilter(), new EndSearchFilter()]),
)
Disponible en 4.4 : méthodes de repository Doctrine
Vous pouvez maintenant pointer directement une opération vers une méthode de votre repository tout en conservant le filtrage et la pagination natifs :
#[GetCollection(stateOptions: new Options(repositoryMethod: 'forPublicApi'))]
public function forPublicApi(): QueryBuilder
{
return $this->createQueryBuilder('v')
->andWhere('v.isPublic = :public')
->setParameter('public', true);
}
Disponible en 4.4 : gestion fine du 404 sur ressource manquante
Lorsqu’un provider renvoie null, vous décidez désormais du comportement par opération : true lève immédiatement une 404, tandis que false laisse le processor prendre le relais.
#[Post(uriTemplate: '/feeders/{id}/feed', read: true, throwOnNotFound: true)]
Disponible en 4.4 : support de la méthode HTTP QUERY
Prise en charge de la RFC 10008 : cette méthode idempotente permet de véhiculer les filtres directement dans le corps de la requête (JSON ou form-urlencoded) :
QUERY /books
Content-Type: application/json
{"name": "api"}
En version 5.0, QueryParameter sait lire automatiquement ces critères depuis le body :
new Query(parameters: [
'name' => new QueryParameter(filter: new PartialSearchFilter()),
])
Puisqu’il s’agit d’un corps de requête, QUERY s’utilise également comme une commande métier avec son propre DTO d’entrée et son processor :
new Query(
input: SearchInput::class,
read: false,
deserialize: true,
write: true,
processor: Search::class,
)
Disponible en 5.0 : identifiants JSON:API
L’attribut id utilisait jusqu’ici une IRI, ce qui déviait de la spécification officielle. Il est possible d’opter pour le nouveau comportement dès la v4.4, et il devient le fonctionnement par défaut en 5.0 :
api_platform:
jsonapi: { use_iri_as_id: false }
{"data":{"id":"10","type":"Book","links":{"self":"/books/10"}}}
Les autres nouveautés notables
- Documentation : OpenAPI 3.2, support de Scalar API Reference et ajout de
withCredentialssur Swagger UI. - JSON-LD / Hydra : préfixes personnalisables au niveau de la ressource via
jsonldContext, et utilisation dehydra:memberAssertionà la place deowl:equivalentClass. - HTTP : attributs de paramètres utilisables sur les propriétés,
routePrioritypour contrôler l’ordre de résolution des routes, et résolution des paramètres de conteneur dans le YAML, le XML et les attributs. - Métadonnées & Outillage :
ApiTestCaseest déplacé dans son propre packageapi-platform/test. L’en-têtecharsetn’est désormais émis que pour les types MIME qui le définissent explicitement. - Dépendances : compatibilité assurée avec Symfony ^7.4 || ^8.0 sur l’ensemble des composants ; le support de la version 6.4 est abandonné.
- Nettoyage 5.0 : suppression des options de configuration dépréciées précédemment (
validator.query_parameter_validation,enable_link_securityetresource_class_directories). Les filtres historiques seront supprimés en 6.0 : vous avez donc tout le temps de migrer sereinement.
Procédure de mise à jour
Pour migrer, nous vous recommandons de passer dans un premier temps sur la version 4.4, corriger les dépréciations, puis effectuer la montée vers la 5.0 :
composer update api-platform/symfony:^4.4
php bin/console api:upgrade-filter
Consultez le guide de migration pour obtenir tous les détails. Si vous utilisez un agent IA pour vos migrations, ce prompt fonctionne particulièrement bien : Follow the upgrade guide at https://api-platform.com/docs/core/upgrade-guide/ and update API Platform to 4.4, fix deprecations, then to 5.0.
Un tout nouvel installateur est également disponible si vous préférez repartir d’une feuille blanche :
curl -fsSL https://api-platform.com/install.sh | sh
api-platform my-api --framework=symfony --with-docker --with-pwa
Une majeure tous les ans !
Nous faisons évoluer notre rythme de release : nous passons d’une version majeure tous les deux ans à une majeure chaque année.
Notre politique de maintenance reste inchangée : correctifs de bugs sur la version stable, correctifs de sécurité sur l’ancienne version old-stable. L’objectif : vous garantir un socle mature et pérenne tout en accélérant nos capacités d’innovation.
Vous souhaitez un accompagnement vers votre migration de version ? Prenez contact avec notre équipe : formation, audit ou renforcement de vos équipes… Nous nous adaptons à vos problématiques.