SlideShare a Scribd company logo
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: use operations to create RPC endpoints
Don’t fight the framework
Enable / Disable Features
use ApiPlatformMetadataPost;
#[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 ApiPlatformMetadataApiResource;
use AppStateBookProvider;
#[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 ApiPlatformMetadataOperation;
use ApiPlatformStateProviderInterface;
use ApiPlatformLaravelEloquentStateItemProvider;
use ApiPlatformDoctrineOrmStateItemProvider;
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 ApiPlatformMetadataOperation;
use ApiPlatformStateProviderInterface;
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 ApiPlatformMetadataOperation;
use ApiPlatformStateProviderInterface;
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
API Platform: The Pragmatic API framework
Use your favorite query builder
use ApiPlatformLaravelEloquentStateOptions;
use IlluminateDatabaseEloquentBuilder;
#[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 ApiPlatformMetadataPost;
#[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
The power of Edge
Side APIs
1
2
3
4
5
Atomic Resource
Pre-generate
HTTP Cache
Preload
Push
edge-side-api.rocks
Embedding...
@api-platform/ld
{
"@id": "/books/1",
"@type": ["https://schema.org/Book"],
"title": "Hyperion",
"author": "https://localhost/authors/1"
}
fetch('/books/1')
@api-platform/ld
{
"@id": "/books/1",
"@type": ["https://schema.org/Book"],
"title": "Hyperion",
"author": "https://localhost/authors/1"
}
fetch('/authors/1')
@api-platform/ld
{
"@id": "/books/1",
"@type": ["https://schema.org/Book"],
"title": "Hyperion",
"author": "https://localhost/authors/1"
}
fetch('/authors/1')
@api-platform/ld
{
"@id": "/books/1",
"@type": ["https://schema.org/Book"],
"title": "Hyperion",
"author": "https://localhost/authors/1"
}
import ld from '@api-platform/ld'
await ld('/books', {
urlPattern: new URLPattern("/authors/:id", "https://localhost")
})
console.log(books.author?.name)
@api-platform/mercure
import mercure, { close } from "@api-platform/mercure";
await mercure('https://localhost/authors/1', {
onUpdate: (author) => console.log(author)
})
Link: </.well-known/mercure>; rel="mercure"
Mercure
✔ Resource live updates
✔ Compatible with Laravel Echo
✔ High Availability as a service
https://mercure.rocks
API Platform: The Pragmatic API framework
@api-platform/ld + @api-
platform/mercure
const fetchFn = (url) => {
return mercure(url).then(d => d.json())
}
ld('/books', { fetchFn: fetchFn, urlPattern: pattern })
.then(books => {
// Do something with books
})
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
API Platform: The Pragmatic API framework
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 !
IRIs collection
GET /books
Content-Type: application/ld+json
{
"@context": "/contexts/Book",
"@id": "/books",
"@type": "Collection",
"totalItems": 4,
"member": [
"/books/1",
"/books/2",
"/books/3",
"/books/4"
]
}
GET /books
Content-Type: application/ld+json
{
"@context": "/contexts/Book",
"@id": "/books",
"@type": "Collection",
"totalItems": 4,
"member": [
{
"@id": "/books/1",
"title": "API Platform",
"author": "/authors/1"
},
{
"@id": "/books/2",
...
},
]
}
use ApiPlatformMetadataApiResource;
#[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 ApiPlatformMetadataGetCollection;
#[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 ApiPlatformMetadataApiProperty;
#[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
API Platform: The Pragmatic API framework
Preload
✔ Preload resources
✔ Server push
✔ Early Hints
✔ Caddy module
https://vulcain.rocks
API Platform: The Pragmatic API framework
API Platform 3.4/4.0
What’s new ?
Query parameters
use ApiPlatformLaravelEloquentFilterPartialSearchFilter;
use ApiPlatformLaravelEloquentFilterOrderFilter;
use ApiPlatformMetadataApiResource;
use ApiPlatformMetadataQueryParameter;
#[ApiResource]
#[QueryParameter(key: 'sort[:property]', filter: OrderFilter::class)]
#[QueryParameter(key: ':property', filter: PartialSearchFilter::class)]
class Book extends Model
{
}
Query parameters
Parameters
✔ 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 ApiPlatformMetadataGetCollection;
use AppExceptionMyDomainException;
#[GetCollection(errors: [MyDomainException::class])]
class Book
{
}
Error management
✔ Exception can be API resources using
ApiPlatformMetadataError
✔ 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)!
API Platform: The Pragmatic API framework
Laravel support
✔ Most of our existing features are useable in a Laravel
project
✔ Authorization and validation use Laravel FormRequest
and policies
✔ Read the documentation: api-platform.com/docs/laravel/
✔ Send feedbacks!
API Platform: The Pragmatic API framework
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/
FIX DEPRECATIONS!
$ composer update
// composer.json
- "api-platform/core": "^3.4",
+ "api-platform/symfony": "^3.4",
+ "api-platform/doctrine-orm": "^3.4",
Step 1
Step 2
Step 3 $ phpunit
Update to API Platform 3.4
api-platform/symfony
Symfony API Platform integration
api-platform/graphql
Build GraphQL enpoints
api-platform/laravel
Laravel API Platform integration
And more

Hydra, JSON-LD, OpenAPI,
JSON Schema etc.
api-platform/doctrine-orm
Doctrine ORM bridge
api-platform/doctrine-odm
Doctrine ODM bridge
Choose your components
api_platform:
- use_symfony_listeners: true
+ use_symfony_listeners: false
defaults:
operations:
- ApiPlatformMetadataGet
- ApiPlatformMetadataGetCollection
- ApiPlatformMetadataPost
- - ApiPlatformMetadataPut
- ApiPlatformMetadataPatch
- ApiPlatformMetadataDelete
serializer:
- hydra_prefix: true
+ hydra_prefix: false
What changed?
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
Hydra prefix?
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"
]
}
GET /books
Content-Type: application/ld+json
{
"@context": "/contexts/Book",
"@id": "/books",
"@type": "hydra:Collection",
"hydra:totalItems": 4,
"hydra:member": [
"/books/73",
"/books/74",
"/books/75",
"/books/76"
]
}
API Platform: The Pragmatic API framework
composer require api-platform/symfony:^4.0.0
Install API Platform 4
composer require api-platform/laravel
Thanks!
SPONSOR ME!
github.com/soyuka

More Related Content

PPT
Lenguaje Ensamblador
PPTX
Sql vs NoSQL-Presentation
PPTX
JSON: The Basics
PPT
04 Cache Memory
PPTX
IntroducciĂłn a TypeScript
PPTX
Segmentation in operating systems
PPT
Actividad 2 Analizador léxico, sintåctico y semåntico
 
Lenguaje Ensamblador
Sql vs NoSQL-Presentation
JSON: The Basics
04 Cache Memory
IntroducciĂłn a TypeScript
Segmentation in operating systems
Actividad 2 Analizador léxico, sintåctico y semåntico
 

What's hot (20)

PDF
Modelo Entidad Relacion E-R
PPTX
Basics of Java
PPTX
Sistemas operativos procesos
PDF
SOAP-based Web Services
PPTX
Introduction to Scala
PDF
3.1 inserciĂłn, eliminaciĂłn y modificaciĂłn de registros
PPTX
Control Statements in Java
PDF
File System Implementation - Part1
PPTX
Protocolos de enrutamiento
PPSX
Data Types & Variables in JAVA
PPTX
ADMINISTRACIÓN DE MEMORIA.pptx
PPTX
Key-Value NoSQL Database
PDF
Operating System Concepts Presentation
PPT
Chapter 13 - I/O Systems
PPT
Multiprocessor Systems
PPTX
Java – lexical issues
PPTX
IntroducciĂłn a DataWarehouse e Inteligencia de Negocios
PPTX
PPTX
Modelo Entidad Relacion E-R
Basics of Java
Sistemas operativos procesos
SOAP-based Web Services
Introduction to Scala
3.1 inserciĂłn, eliminaciĂłn y modificaciĂłn de registros
Control Statements in Java
File System Implementation - Part1
Protocolos de enrutamiento
Data Types & Variables in JAVA
ADMINISTRACIÓN DE MEMORIA.pptx
Key-Value NoSQL Database
Operating System Concepts Presentation
Chapter 13 - I/O Systems
Multiprocessor Systems
Java – lexical issues
IntroducciĂłn a DataWarehouse e Inteligencia de Negocios
Ad

Similar to API Platform: The Pragmatic API framework (20)

PPTX
REST API Best Practices & Implementing in Codeigniter
PDF
RESTful API development in Laravel 4 - Christopher Pecoraro
PDF
What's New In Laravel 5
PDF
Creating a modern web application using Symfony API Platform, ReactJS and Red...
PDF
Creating a modern web application using Symfony API Platform Atlanta
PPTX
Laravel 5
PDF
Supercharging WordPress Development in 2018
PDF
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngine
PDF
Practices and tools for building better APIs
 
PDF
Practices and tools for building better API (JFall 2013)
PPTX
REST APIs in Laravel 101
PDF
High quality ap is with api platform
PDF
How to disassemble one monster app into an ecosystem of 30
 
PPTX
Design Summit - RESTful API Overview - John Hardy
KEY
How and why i roll my own node.js framework
PPTX
Using WordPress as your application stack
PDF
iOS Swift application architecture
PPTX
API Workshop: Deep dive into REST APIs
PPS
Simplify your professional web development with symfony
PPT
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
REST API Best Practices & Implementing in Codeigniter
RESTful API development in Laravel 4 - Christopher Pecoraro
What's New In Laravel 5
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform Atlanta
Laravel 5
Supercharging WordPress Development in 2018
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngine
Practices and tools for building better APIs
 
Practices and tools for building better API (JFall 2013)
REST APIs in Laravel 101
High quality ap is with api platform
How to disassemble one monster app into an ecosystem of 30
 
Design Summit - RESTful API Overview - John Hardy
How and why i roll my own node.js framework
Using WordPress as your application stack
iOS Swift application architecture
API Workshop: Deep dive into REST APIs
Simplify your professional web development with symfony
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Ad

Recently uploaded (20)

PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
Transform Your Business with a Software ERP System
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Nekopoi APK 2025 free lastest update
PPT
Introduction Database Management System for Course Database
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
L1 - Introduction to python Backend.pptx
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Designing Intelligence for the Shop Floor.pdf
PDF
Digital Systems & Binary Numbers (comprehensive )
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
top salesforce developer skills in 2025.pdf
PDF
System and Network Administration Chapter 2
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Reimagine Home Health with the Power of Agentic AI​
Wondershare Filmora 15 Crack With Activation Key [2025
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Transform Your Business with a Software ERP System
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Nekopoi APK 2025 free lastest update
Introduction Database Management System for Course Database
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
L1 - Introduction to python Backend.pptx
PTS Company Brochure 2025 (1).pdf.......
Designing Intelligence for the Shop Floor.pdf
Digital Systems & Binary Numbers (comprehensive )
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Which alternative to Crystal Reports is best for small or large businesses.pdf
2025 Textile ERP Trends: SAP, Odoo & Oracle
Operating system designcfffgfgggggggvggggggggg
top salesforce developer skills in 2025.pdf
System and Network Administration Chapter 2

API Platform: The Pragmatic API framework

  • 1. The pragmatic API framework API PLATFORM CON 2024 - LILLE, FRANCE & ONLINE
  • 2. API PLATFORM CON 2023 - LILLE, FRANCE & ONLINE API PLATFORM 4
  • 3. About Me ✔ API Platform release manager ✔ CTO at Les-Tilleuls.coop ✔ Developer, biker, builder ✔ Recent father Antoine Bluchet [email protected] @s0yuka soyuka.me
  • 4. with API Platform Pragmatic API development
  • 5. 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: use operations to create RPC endpoints Don’t fight the framework
  • 6. Enable / Disable Features use ApiPlatformMetadataPost; #[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 {}
  • 7. use ApiPlatformMetadataApiResource; use AppStateBookProvider; #[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
  • 8. use ApiPlatformMetadataOperation; use ApiPlatformStateProviderInterface; use ApiPlatformLaravelEloquentStateItemProvider; use ApiPlatformDoctrineOrmStateItemProvider; 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
  • 9. use ApiPlatformMetadataOperation; use ApiPlatformStateProviderInterface; 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
  • 10. use ApiPlatformMetadataOperation; use ApiPlatformStateProviderInterface; 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
  • 12. Use your favorite query builder use ApiPlatformLaravelEloquentStateOptions; use IlluminateDatabaseEloquentBuilder; #[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
  • 13. use ApiPlatformMetadataPost; #[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
  • 15. Why you should use API Platform commit f55cfce9c014655dd5343a5f20dfaf9ec5df2da0 Author: KĂ©vin Dunglas <[email protected]> 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
  • 16. The power of Edge Side APIs
  • 19. @api-platform/ld { "@id": "/books/1", "@type": ["https://schema.org/Book"], "title": "Hyperion", "author": "https://localhost/authors/1" } fetch('/books/1')
  • 20. @api-platform/ld { "@id": "/books/1", "@type": ["https://schema.org/Book"], "title": "Hyperion", "author": "https://localhost/authors/1" } fetch('/authors/1')
  • 21. @api-platform/ld { "@id": "/books/1", "@type": ["https://schema.org/Book"], "title": "Hyperion", "author": "https://localhost/authors/1" } fetch('/authors/1')
  • 22. @api-platform/ld { "@id": "/books/1", "@type": ["https://schema.org/Book"], "title": "Hyperion", "author": "https://localhost/authors/1" } import ld from '@api-platform/ld' await ld('/books', { urlPattern: new URLPattern("/authors/:id", "https://localhost") }) console.log(books.author?.name)
  • 23. @api-platform/mercure import mercure, { close } from "@api-platform/mercure"; await mercure('https://localhost/authors/1', { onUpdate: (author) => console.log(author) }) Link: </.well-known/mercure>; rel="mercure"
  • 24. Mercure ✔ Resource live updates ✔ Compatible with Laravel Echo ✔ High Availability as a service https://mercure.rocks
  • 26. @api-platform/ld + @api- platform/mercure const fetchFn = (url) => { return mercure(url).then(d => d.json()) } ld('/books', { fetchFn: fetchFn, urlPattern: pattern }) .then(books => { // Do something with books })
  • 27. 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
  • 29. 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 !
  • 30. IRIs collection GET /books Content-Type: application/ld+json { "@context": "/contexts/Book", "@id": "/books", "@type": "Collection", "totalItems": 4, "member": [ "/books/1", "/books/2", "/books/3", "/books/4" ] } GET /books Content-Type: application/ld+json { "@context": "/contexts/Book", "@id": "/books", "@type": "Collection", "totalItems": 4, "member": [ { "@id": "/books/1", "title": "API Platform", "author": "/authors/1" }, { "@id": "/books/2", ... }, ] }
  • 31. use ApiPlatformMetadataApiResource; #[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" ] }
  • 32. use ApiPlatformMetadataGetCollection; #[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
  • 33. use ApiPlatformMetadataApiProperty; #[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
  • 35. Preload ✔ Preload resources ✔ Server push ✔ Early Hints ✔ Caddy module https://vulcain.rocks
  • 38. Query parameters use ApiPlatformLaravelEloquentFilterPartialSearchFilter; use ApiPlatformLaravelEloquentFilterOrderFilter; use ApiPlatformMetadataApiResource; use ApiPlatformMetadataQueryParameter; #[ApiResource] #[QueryParameter(key: 'sort[:property]', filter: OrderFilter::class)] #[QueryParameter(key: ':property', filter: PartialSearchFilter::class)] class Book extends Model { }
  • 40. Parameters ✔ 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
  • 41. Error management use ApiPlatformMetadataGetCollection; use AppExceptionMyDomainException; #[GetCollection(errors: [MyDomainException::class])] class Book { }
  • 42. Error management ✔ Exception can be API resources using ApiPlatformMetadataError ✔ 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)!
  • 44. Laravel support ✔ Most of our existing features are useable in a Laravel project ✔ Authorization and validation use Laravel FormRequest and policies ✔ Read the documentation: api-platform.com/docs/laravel/ ✔ Send feedbacks!
  • 46. 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 !
  • 47. From v3 to v4 How to update?
  • 48. $ composer require api-platform/core:^3.4 Update to API Platform 3.4 api-platform.com/docs/core/upgrade-guide/
  • 50. $ composer update // composer.json - "api-platform/core": "^3.4", + "api-platform/symfony": "^3.4", + "api-platform/doctrine-orm": "^3.4", Step 1 Step 2 Step 3 $ phpunit Update to API Platform 3.4
  • 51. api-platform/symfony Symfony API Platform integration api-platform/graphql Build GraphQL enpoints api-platform/laravel Laravel API Platform integration And more
 Hydra, JSON-LD, OpenAPI, JSON Schema etc. api-platform/doctrine-orm Doctrine ORM bridge api-platform/doctrine-odm Doctrine ODM bridge Choose your components
  • 52. api_platform: - use_symfony_listeners: true + use_symfony_listeners: false defaults: operations: - ApiPlatformMetadataGet - ApiPlatformMetadataGetCollection - ApiPlatformMetadataPost - - ApiPlatformMetadataPut - ApiPlatformMetadataPatch - ApiPlatformMetadataDelete serializer: - hydra_prefix: true + hydra_prefix: false What changed?
  • 53. 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
  • 54. Hydra prefix? 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" ] } GET /books Content-Type: application/ld+json { "@context": "/contexts/Book", "@id": "/books", "@type": "hydra:Collection", "hydra:totalItems": 4, "hydra:member": [ "/books/73", "/books/74", "/books/75", "/books/76" ] }
  • 56. composer require api-platform/symfony:^4.0.0 Install API Platform 4 composer require api-platform/laravel

Editor's Notes

  • #13: If you need a controller, use Symfony or Laravel in their standard way.
  • #14: Day 2 16:10 PM - 16:50 PM
  • #18: edge-side-api.rocks demonstration
  • #25: Utiliser RabbitMQ avec Symfony et API Platform. 16h30
  • #34: Day 2 16:10 PM - 16:50 PM
  • #44: 15:20 PM - 16:00 PM day 1
  • #49: If a class does not exists it moved to the ApiPlatform\Metadata namespace.
  • #51: If a class does not exists it moved to the ApiPlatform\Metadata namespace.
  • #56: Day2 14:50 PM - 15:30 PM
  • #61: If you need a controller, use Symfony or Laravel in their standard way.
  • #62: If you need a controller, use Symfony or Laravel in their standard way.
  • #63: If you need a controller, use Symfony or Laravel in their standard way.
  • #64: If you need a controller, use Symfony or Laravel in their standard way.