API Platform
Un framework PHP complet pour créer des API REST et GraphQL modernes, avec une génération automatique de documentation et de clients.
Qu'est-ce qu'API Platform ?
Imaginez que vous construisiez une application moderne. Aujourd'hui, les applications sont souvent découpées en plusieurs parties : un backend qui gère les données et la logique métier, et un frontend (voire plusieurs) qui affiche l'interface utilisateur. Ces différentes parties communiquent via des API (interfaces de programmation).
API Platform est un framework basé sur
Symfony qui permet de créer ces API de manière extrêmement simple et efficace. C'est comme un atelier complètement équipé pour construire des API professionnelles sans avoir à réinventer la roue.
Pourquoi API Platform est si puissant ?
Développement accéléré
Créez des API en quelques minutes en décrivant simplement vos modèles de données, sans écrire de code répétitif.
Standards modernes
Construit sur les normes web et les meilleures pratiques : JSON-LD, Hydra, OpenAPI, GraphQL, et plus encore.
En résumé, API Platform permet aux entreprises et développeurs de créer rapidement des API performantes et bien documentées, tout en réduisant considérablement le temps de développement et les coûts associés.
Fonctionnement technique
API Platform est un framework
PHP construit sur
Symfony qui permet de créer des API RESTful et GraphQL en suivant les meilleures pratiques et standards du web.
Les concepts fondamentaux
Ressources API
Dans API Platform, vous définissez des ressources en ajoutant des annotations ou des attributs à vos entités Doctrine. C'est cette déclaration qui génère automatiquement les endpoints API.
<?php
// src/Entity/Book.php
namespace AppEntity;
use ApiPlatformMetadataApiResource;
use ApiPlatformMetadataGet;
use ApiPlatformMetadataGetCollection;
use ApiPlatformMetadataPost;
use ApiPlatformMetadataPut;
use ApiPlatformMetadataDelete;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
#[ORMEntity]
#[ApiResource(
operations: [
new Get(),
new GetCollection(),
new Post(),
new Put(),
new Delete()
],
paginationItemsPerPage: 10,
normalizationContext: ['groups' => ['book:read']],
denormalizationContext: ['groups' => ['book:write']]
)]
class Book
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn]
private ?int $id = null;
#[ORMColumn(length: 255)]
#[AssertNotBlank]
#[AssertLength(min: 2, max: 255)]
private string $title;
#[ORMColumn(type: 'text', nullable: true)]
private ?string $description = null;
#[ORMColumn]
#[AssertNotNull]
#[AssertGreaterThan(0)]
private float $price;
#[ORMManyToOne(targetEntity: Author::class, inversedBy: 'books')]
#[ORMJoinColumn(nullable: false)]
private Author $author;
// Getters and setters...
}
Opérations personnalisées
Au-delà des opérations CRUD standards, vous pouvez définir des opérations personnalisées pour des actions spécifiques à votre logique métier.
<?php
// src/Controller/BookController.php
namespace AppController;
use AppEntityBook;
use AppRepositoryBookRepository;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentRoutingAnnotationRoute;
class BookController extends AbstractController
{
#[Route(
path: '/api/books/featured',
name: 'api_books_featured',
methods: ['GET'],
defaults: [
'_api_resource_class' => Book::class,
'_api_operation_name' => 'featured'
]
)]
public function getFeaturedBooks(BookRepository $bookRepository): JsonResponse
{
$featuredBooks = $bookRepository->findFeaturedBooks();
return $this->json(['featured' => $featuredBooks], 200, [], [
'groups' => ['book:read']
]);
}
#[Route(
path: '/api/books/{id}/toggle-availability',
name: 'api_book_toggle_availability',
methods: ['POST'],
defaults: [
'_api_resource_class' => Book::class,
'_api_operation_name' => 'toggle_availability'
]
)]
public function toggleAvailability(Book $book): JsonResponse
{
$book->setAvailable(!$book->isAvailable());
$this->getDoctrine()->getManager()->flush();
return $this->json(['available' => $book->isAvailable()], 200, [], [
'groups' => ['book:read']
]);
}
}
Support GraphQL
API Platform génère automatiquement un schéma GraphQL à partir de vos ressources, permettant d'exposer la même API à la fois en REST et en GraphQL.
# Query example
query GetBooks {
books {
edges {
node {
id
title
description
price
author {
name
email
}
}
}
}
}
# Mutation example
mutation CreateBook {
createBook(input: {
title: "API Platform - In Action"
description: "A practical guide to API Platform"
price: 25.99
author: "/api/authors/1" # IRI for author with ID 1
}) {
book {
id
title
}
}
}
Intégration frontend
API Platform facilite l'intégration avec des frameworks frontend modernes comme React,
Vue.js ou
Next.js grâce à ses clients générés automatiquement.
<template>
<div>
<h1>Books List</h1>
<div v-if="loading">Loading books...</div>
<div v-else>
<ul>
<li v-for="book in books" :key="book.id">
<h3>{{ book.title }}</h3>
<p>{{ book.description }}</p>
<p><strong>€{{ book.price }}</strong></p>
<p>Author: {{ book.author.name }}</p>
<button @click="toggleAvailability(book.id)">Toggle Availability</button>
</li>
</ul>
<div class="pagination">
<button :disabled="currentPage === 1" @click="fetchPage(currentPage - 1)">
Previous
</button>
<span>Page {{ currentPage }} of {{ totalPages }}</span>
<button :disabled="currentPage === totalPages" @click="fetchPage(currentPage + 1)">
Next
</button>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
books: [],
loading: true,
currentPage: 1,
totalPages: 1
};
},
created() {
this.fetchBooks();
},
methods: {
async fetchBooks() {
this.loading = true;
try {
const response = await axios.get(`/api/books?page=${this.currentPage}`);
this.books = response.data['hydra:member'];
this.totalPages = Math.ceil(
response.data['hydra:totalItems'] / response.data['hydra:view']['hydra:itemsPerPage']
);
} catch (error) {
console.error('Error fetching books', error);
} finally {
this.loading = false;
}
},
fetchPage(page) {
this.currentPage = page;
this.fetchBooks();
},
async toggleAvailability(id) {
try {
await axios.post(`/api/books/${id}/toggle-availability`);
// Refresh books list
this.fetchBooks();
} catch (error) {
console.error('Error toggling availability', error);
}
}
}
};
</script>
Fonctionnalités principales
- API REST et GraphQL - Exposition de vos données via les deux formats les plus populaires
- Génération de documentation - Documentation interactive OpenAPI (Swagger UI), Hydra
- Filtres et tri - Système avancé de filtrage, pagination et tri
- Sécurité - Intégration avec le système de sécurité de Symfony, JWT, OAuth
- Négociation de contenu - Formats multiples: JSON-LD, HAL, JSON:API, CSV, XML, YAML
- Admin générée - Interface d'administration générée automatiquement
- Génération de clients - Génère des clients JavaScript pour React, Vue.js, etc.
- Performances - Système de cache intégré, optimisations pour la production
L'écosystème API Platform
- API Platform Core - Le composant principal pour créer des API
- Admin Component - Interface d'administration basée sur React Admin
- Client Generator - Génère des clients pour divers frameworks frontend
- Schema Generator - Crée des modèles à partir de schémas existants
- API Platform Distribution - Distribution Docker complète incluant NGINX, PHP-FPM, PostgreSQL, etc.
- API Platform Cloud - Solution cloud pour déployer rapidement des API
Cas d'usage
Applications SPA et PWA
Parfait pour alimenter des applications Single Page (SPA) ou Progressive Web Apps (PWA) développées avec React, Vue.js ou Angular.
Applications mobiles
Fournit un backend performant pour les applications mobiles iOS et Android, avec une communication efficace et standardisée.
API publiques
Idéal pour créer des API publiques pour des partenaires ou des développeurs tiers, avec documentation complète et formats standardisés.
Architecture microservices
Simplifiez la création de microservices bien documentés qui communiquent via des API standardisées.
Entreprises qui utilisent API Platform
De nombreuses entreprises font confiance à API Platform pour leurs API critiques :