API Platform 4.2 - Redefining API Development
# API Platform 4.2: Redefining API Development
I’m thrilled to announce the release of API Platform 4.2, unveiled at the 5th edition of the API Platform Conference in Lille! As the release manager, I’m incredibly proud of the work our community has put into this version. Let’s dive into what makes this release so special.
Since version 4.0, the API Platform community has been hard at work. We’ve seen an incredible amount of activity:
- 610 commits have been merged.
- We’ve added 189,945 lines of code and removed 328,879.
- Out of 291 issues opened, a remarkable 230 have been closed.
This wouldn’t be possible without the support of our amazing community and sponsors. A huge thank you to everyone who has contributed!
Check out my conference slides:
This release is packed with features that will improve your developer experience and the performance of your APIs.
# Enhanced Metadata Management
We’re introducing more flexible ways to manage your API resource metadata.
# PHP File Metadata
You can now define your API resources and their operations in PHP files, giving you more control and separating the configuration from your domain objects.
// config/api_platform/resources/speaker.php
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Operations;
use ApiPlatform\Metadata\Post;
use App\Entity\Speaker;
return (new ApiResource())
->withClass(Speaker::class)
->withOperations(new Operations([
new Post(),
new Get(),
new GetCollection(),
]))
;
# Metadata Mutators
For more dynamic control over your resources and operations, you can now use Metadata Mutators. This allows you to programmatically alter the metadata of your resources and operations.
use ApiPlatform\Metadata\AsResourceMutator;
use ApiPlatform\Metadata\ApiResource;
use App\Entity\Speaker;
#[AsResourceMutator(resourceClass: Speaker::class)]
final class SpeakerResourceMutator
{
public function __invoke(ApiResource $resource): ApiResource
{
$operations = $resource->getOperations();
$operations->remove('_api_Speaker_get_collection');
return $resource->withOperations($operations);
}
}
# From API Filter to Parameters
We’re moving away from the legacy ApiFilter to a more powerful and explicit QueryParameter system. This change is designed to improve clarity and give you more control over how your API handles query parameters. This new approach separates the responsibilities of filtering, documentation, and validation.
We’ve also introduced new ORM/ODM filters to make common tasks easier:
- ExactFilter
- IriFilter
- PartialSearchFilter
- OrFilter
- FreeTextQueryFilter
This finally closes issue #2400 closing a 7 year old issue!
Here’s how you can implement a free-text search:
use ApiPlatform\Doctrine\Orm\Filter\FreeTextQueryFilter;
use ApiPlatform\Doctrine\Orm\Filter\PartialSearchFilter;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\QueryParameter;
#[GetCollection(
parameters: [
'q' => new QueryParameter(
filter: new FreeTextQueryFilter(new PartialSearchFilter()),
properties: ['name', 'ean'],
),
],
)]
class Book {}
# URI Variable Provider
For more complex scenarios, you can now use a provider on a Link to process URI variables. This is particularly useful for subresource queries where you need to fetch an entity from a URI segment.
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ParameterProvider\ReadLinkParameterProvider;
#[Get(
uriTemplate: '/company/{company}/employee/{id}',
uriVariables: [
'company' => new Link(
provider: ReadLinkParameterProvider::class,
fromClass: Company::class
),
'id'
],
provider: EmployeeProvider::class
)]
class Employee
{
public string $id;
}
# Performance and Specification Improvements
API Platform 4.2 brings significant performance enhancements. FrankenPHP
With FrankenPHP, you can expect a massive performance boost. Our benchmarks on a Sylius application show that FrankenPHP in worker mode can handle up to 3 times more requests per second compared to a traditional Nginx + FPM setup.
Check out our benchmarks at github.com/soyuka/sylius-benchmarks
# JSON Streamer
For high-performance scenarios, you can now opt-in to use our new JSON streamer. It’s compatible with JSON and JSON-LD/Hydra and can significantly speed up the serialization of large collections. In our tests with a Sylius API, we saw a ~32.4% increase in requests per second.
# State Options and the Object Mapper
A powerful feature that gained popularity thanks to Symfony Casts is the ability to use a different object for your API resource than your entity. In API Platform 4.2, this is now powered by the new Symfony Object Mapper component. This allows you to create dedicated API resources that map to your entities, giving you more control over your API’s public interface. A huge thank you to Ryan Weaver for popularizing this concept!
# OpenAPI & JSON Schema
We’ve mutualized the JSON Schema in our OpenAPI specification, resulting in a 30% smaller file size. This reduces the I/O intensity and makes your API documentation faster to load and parse. We’ve also improved the specification with root-level tags, license information, and better default value handling.
# Laravel Support
The API Platform integration for Laravel is better than ever! With 124 merged pull requests and 79 of 99 issues closed, we’re getting closer to feature parity with our Symfony integration. A big shout-out to our top Laravel contributors for their amazing work! Get Started with API Platform 4.2
Ready to upgrade? It’s as simple as running:
composer update api-platform/symfony:^4.2
# The Future: API Platform 5.0
Happy Birthday API Platform!

We’re already looking ahead to API Platform 5.0! We’ll be deprecating the old ApiFilter system in favor of the new Parameter system, and we’ll continue to improve the JSON streamer and Object Mapper.
Thank you for being part of this incredible journey. We can’t wait to see what you build with API Platform 4.2!
Check out the full changelog for more informations.
P.S. Don’t forget to sponsor me on GitHub if you love what we’re doing! github.com/soyuka