API Platform 5.0 is out, and it carries every change from the 4.4.0 release that shipped the same day, plus a set of removals that have been scheduled for this major for a while. The headline is support for the HTTP QUERY method, which became a standard back in June.
Some of the highlights include:
- HTTP QUERY method support, following RFC 10008
- OpenAPI 3.2.0 support, and Scalar API Reference as a documentation option
- A rebuilt Doctrine filter set, with a codemod to migrate off the old one
- Denormalization errors on constrained properties now return
422instead of400 ApiTestCasemoved into its ownapi-platform/testpackage- Symfony 6.4 support dropped, with
^7.4 || ^8.0now required
What's New
HTTP QUERY Method Support
QUERY is a new HTTP method, published as RFC 10008 in June 2026. It works like POST in that the request carries its content in a body, but the spec defines it as safe and idempotent, so a client or a proxy can repeat it without worrying about partial state changes.
That makes it a fit for search and filter requests that have outgrown a URL query string. You get to send a structured body without claiming the request might change something on the server.
PR: #8349
The Doctrine Filters Were Rebuilt
This is the largest piece of work in the release, and it lands across both ORM and ODM. OrFilter and ComparisonFilter are out of @experimental and are now covered by the backward compatibility promise. ComparisonFilter also picked up a between operator.
There are new filters too:
ChainFiltercomposes several filters onto one parameterStartSearchFilterandWordStartSearchFiltermatch at the start of a value or a wordEndSearchFiltermatches at the endDateandExistsfilters now have standalone formsFreeTextQueryFiltertakes a per-property filter map
The old filters are on the way out. The legacy SearchFilter, BooleanFilter, NumericFilter, BackedEnumFilter and OrderFilter are deprecated, along with the AbstractFilter base class and RangeFilter. Rather than leaving you to find every one by hand, there's an api:upgrade-filter command that rewrites them for you.
OpenAPI 3.2.0 and Scalar
The generated OpenAPI document now supports version 3.2.0, and Scalar API Reference joins Swagger UI and Redoc as a way to render your docs.
Validation Errors Changed Shape
This one is worth reading twice before you upgrade. When denormalization fails on a property that carries a Symfony Validator constraint, the response is now 422 with a ConstraintViolation payload, where it used to be 400 with a hydra:Error payload. Properties with no constraint metadata still return 400.
There's no configuration flag to turn this off. If you need the old behavior, you override the api_platform.state.denormalization_violation_factory service. The change was written during the 4.4 betas and then held back for 5.0, so 4.4.0 itself keeps the 4.3 behavior.
Separately, Doctrine's UniqueConstraintViolationException joins the default exception_to_status map at 422, sitting alongside the OptimisticLockException entry that already mapped to 409.
ApiTestCase Has Its Own Package
ApiTestCase and its helpers moved to a new api-platform/test package. The classes in the old ApiPlatform\Symfony\Bundle\Test namespace still work, but they're deprecated and go away in 6.0.
PR: #7887
Smaller Additions
A few more changes worth knowing about:
routePrioritylets you control the order routes are matched in- Swagger UI and GraphiQL scripts now emit a CSP nonce
%param%placeholders resolve in YAML, XML and attribute resource configParameterattributes work on properties, and can be restricted to specific operations- Symfony security voters can expose their reasons
- A
throwOnNotFoundmetadata option - HEAD requests skip the response body
Upgrade Notes
API Platform 5.0 requires Symfony ^7.4 || ^8.0, and support for 6.4 is dropped. api-platform/doctrine-orm needs doctrine/orm ^2.17 || ^3.3, and doctrine/doctrine-bundle moves to ^2.11.1 || ^3.1.
The breaking changes to check against your own code:
- The JSON:API
use_iri_as_idoption now defaults tofalse - The legacy PropertyInfo Type system is removed
DeserializeProviderno longer supportsTranslatorInterface- The
Request::getContentType()fallbacks are gone - The Symfony 6 value resolver shim is gone
- APIs deprecated for removal in 5.0 are removed
If you're not ready for the major, 4.4.0 shipped the same day with the features and none of the removals.
Install it with Composer:
composer require api-platform/core:^5.0