API Platform 4.0 got released. Discover Pragmatic API development with API Platform.
Size: 27.8 MB
Language: en
Added: Sep 23, 2024
Slides: 57 pages
Slide Content
The pragmatic API framework API PLATFORM CON 2024 - LILLE, FRANCE & ONLINE
API PLATFORM CON 2023 - LILLE, FRANCE & ONLINE API PLATFORM 4
About Me API Platform release manager CTO at Les-Tilleuls.coop Developer, biker, builder Recent father Antoine Bluchet soyuka @phpc.social @s0yuka soyuka .me
with API Platform Pragmatic API development
Pragmatic API development Enable (or disable) the features you (don’t) need Decorate our extension points (IRI Converter, providers , processors, etc. ) API Platform segregates commands and queries It’s not always CRUD: u se operations to create RPC endpoints Don’t fight the framework
Enable / Disable Features use ApiPlatform\Metadata\Post; #[ Post ( read : true , // to call the provider write : true , // to call the processor deserialize : false , // transforms the request body to this resource's class serialize : false , // transforms the provider's response to JSON validate : false , // validates the user input queryParameterValidationEnabled : false , // validates query parameters output : false , // using false will return nothing openapi : false , // disables the OpenAPI documentation )] class Book {}
use ApiPlatform\Metadata\ApiResource; use App\State\BookProvider; #[ Put ( uriTemplate : '/books/{id}' , allowCreate : true , // create a new value through a PUT operation provider : BookProvider :: class , processor : BookProcessor :: class , )] class Book { } State Provider / Processor
use ApiPlatform\Metadata\Operation; use ApiPlatform\State\ProviderInterface; use ApiPlatform\Laravel\Eloquent\State\ItemProvider; use ApiPlatform\Doctrine\Orm\State\ItemProvider; final readonly class BookProvider implements ProviderInterface { public function __construct( private ItemProvider $itemProvider ) {} public function provide( Operation $operation , array $uriVariables = [], array $context … { return $this -> itemProvider ->provide( $operation , $uriVariables , $context ); } } Decorate the state providers
use ApiPlatform\Metadata\Operation; use ApiPlatform\State\ProviderInterface; final class BookProvider implements ProviderInterface { public function provide( Operation $operation , array $uriVariables = [], array $context … { $dbh = new \ PDO ( 'sqlite:/db.sqlite' ); $sth = $dbh ->prepare( 'SELECT * FROM book WHERE id = :id' ); $sth ->bindParam( 'id' , $uriVariables [ 'id' ], \ PDO :: PARAM_STR ); $sth ->execute(); return !( $result = $sth ->fetch()) ? null : $result ; } } Any data source
use ApiPlatform\Metadata\Operation; use ApiPlatform\State\ProviderInterface; final class BookProvider implements ProviderInterface { public function provide( Operation $operation , array $uriVariables = [], array $context … { return json_decode( file_get_contents( 'https://demo.api-platform.com/api/books.jsonld' ) ); } } Any data source
Use your favorite query builder use ApiPlatform\Laravel\Eloquent\State\Options; use Illuminate\Database\Eloquent\Builder; #[ GetCollection ( uriTemplate : '/author/{author}/books' , uriVariables : [ 'author' ], stateOptions : new Options ( handleLinks : [ self :: class , 'handleLinks' ] ) )] class Employee { public static function handleLinks( Builder $builder , array $uriVariables , array $context ): Builder { $builder ->where( 'books.author_id' , $uriVariables [ 'author' ]); } } AVAILABLE FOR Doctrine ORM Doctrine ODM Laravel Eloquent Elasticsearch ESQL
use ApiPlatform\Metadata\Post; #[ Post ( uriTemplate : '/rpc' , processor : [ self :: class , 'process' ])] final readonly class PostContent { public function __construct( public string $name ) {} public static function process( mixed $data ) { // do something with $data } } RPC endpoints
Not convinced?
Why you should use API Platform commit f55cfce9c014655dd5343a5f20dfaf9ec5df2da0 Author: Kévin Dunglas < dunglas @ gmail . com > Date: Tue Jan 20 00:16:57 2015 + 0100 first commit REST oriented JSON-LD , JSON:API serialization OpenAPI, Hydra, JSON Schema documentation URI based mechanics (cache, live updates, relations etc.) Embedded content negotiation, validation and authorization 10 years of existence in January
Client tools Admin generator @api-platform/admin Manage topics on a single EventSource connection @api-platform/mercure Replace fetch by @api-platform/ld for linked data And more at api-platform.com
Atomic resources? Small and atomic documents Don’t embed resources, use URIs instead Better browser and share cache hit rate Clients fetch only what they initially need and update only small chunks of data Hypermedia is at the heart of Edge Side APIs (JSON-LD, Hydra, JSON:API) Read our white paper !
use ApiPlatform\Metadata\ApiResource; #[ ApiResource ( normalizationContext : [ 'iri_only' => true ], )] final readonly class Book { } IRI Only GET /books Content-Type : application/ld+json { "@context" : "/contexts/Book" , "@id" : "/books" , "@type" : "Collection" , "totalItems" : 4 , "member" : [ "/books/73" , "/books/74" , "/books/75" , "/books/76" ] }
use ApiPlatform\Metadata\GetCollection; #[ ApiResource ( uriTemplate : ' /authors/{author}/books ' , uriVariables : [ 'author' => new Link ( fromClass : Author :: class , toProperty : 'author' ) ], normalizationContext : [ 'iri_only' => true ], )] final readonly class Book { } Group data with IRIs
use ApiPlatform\Metadata\ApiProperty; #[ ApiProperty ( property : 'books' , uriTemplate : '/authors/{author}/books' )] final readonly class Author { } GET /authors/1 Content-Type : application/ld+json { "@context" : "/contexts/Book" , "@id" : "/authors/1" , "@type" : "Author" , " books " : " /authors/1/books " } Group data with IRIs
Preload Preload resources Server push Early Hints Caddy module https://vulcain.rocks
API Platform 3.4/4.0 What’s new ?
Query parameters use ApiPlatform\Laravel\Eloquent\Filter\PartialSearchFilter; use ApiPlatform\Laravel\Eloquent\Filter\OrderFilter; use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\QueryParameter; #[ ApiResource ] #[ QueryParameter ( key : 'sort[:property]' , filter : OrderFilter :: class )] #[ QueryParameter ( key : ':property' , filter : PartialSearchFilter :: class )] class Book extends Model { }
Query parameters
Query parameters Header / Query parameter JSON Schema validation OpenAPI and Hydra compatible :property placeholder for better DX Better filter composition (OrFilter, decorate D octrine filters etc.) Filter aliasing
P arameters Header / Query parameter JSON Schema validation OpenAPI and Hydra compatible :property placeholder for better DX Better filter composition (OrFilter, decorate Doctrine filters etc.) Filter aliasing
Error management use ApiPlatform\Metadata\GetCollection; use App\Exception\MyDomainException; #[ GetCollection ( errors : [ MyDomainException :: class ])] class Book { }
Error management Exception can be API resources using ApiPlatform\Metadata\Error Specify errors in an operation to document them with OpenAPI Read our guides: api-platform.com/docs/guides/error-provider/ api-platform.com/docs/guides/error-resource/ Exception are automatically rendered using the Problem details specification (RFC 7807)!
Laravel support Most of our existing features are useable in a Laravel project Authorization and validation use Laravel FormRequest and policies Read the documentation: a pi-platform.com/docs/laravel/ Send feedbacks!
And way more… Doctrine ENUM filter Serializer default context fixes with an option to change the deserializer type Static headers Inflector is now a service Configure whether to override OpenAPI responses Read the CHANGELOG !
From v3 to v4 How to update?
$ composer require api-platform/core:^3.4 Update to API Platform 3.4 api-platform.com/docs/core/upgrade-guide/
What changed? No more PUT operation by default Hydra prefix disabled ApiPlatform/{Api,Exception} moved to ApiPlatform/Metadata Listeners are no longer used* * only useful when using controllers on API Resources
Error management Static HTTP Headers Denormalize type Query Parameter New in API Platform 3.4 / 4.0
Error management Static HTTP Headers Denormalize type Query Parameter New in API Platform 3.4 / 4.0
New in API Platform 3.4 / 4.0 POST /import HTTP/2 Content-Type : application/json [{ "name" : "Kévin" }, { "name" : "Antoine" }]
use ApiPlatform \ Metadata \ Post ; class ValueObject { public string $name ; } #[ Post ( uriTemplate : '/import' , denormalizationContext : [ 'deserializer_type' : 'ValueObject[]' ], validate : false , // we don't validate lists processor : [ self :: class , 'process' ] )] class Book { public static function process ( mixed $data ) { // Do something with the list of ValueObject } } New in API Platform 3.4 / 4.0 custom validation => processor