Le blog

Introduction à API Platform pour Laravel

Publié le 06 novembre 2024

Initialement évoqué par Antoine Bluchet lors du Forum PHP 2023, le support officiel de Laravel par API Platform a officiellement été annoncé par Kévin Dunglas le 19 septembre dernier durant la keynote d’ouverture de l’API Platform Conference. C'est désormais le moyen le plus simple de créer des API web de pointe en utilisant Laravel ! Pour rappel, API Platform est un ensemble d'outils permettant de construire des projets web modernes. Comme d'autres frameworks récents tels que Laravel et Symfony, API Platform est à la fois un framework complet tout-en-un et un ensemble de composants et de bundles PHP et JS indépendants pouvant être utilisés séparément. Découvrons à travers cet article les principales fonctionnalités et nouveautés qu’apporte cette révolution.

API Platform pour Laravel" class="wp-image-10278#

Tour d’horizon des fonctionnalités d’API Platform pour Laravel

Avec API Platform pour Laravel, vous pouvez :

#

Installer Laravel

API Platform peut s’installer facilement sur des projets Laravel, qu'ils soient nouveaux ou existants. Si vous avez déjà un projet en place, passez directement au chapitre suivant. Sinon, créez un nouveau projet Laravel. Toutes les méthodes d'installation de Laravel sont prises en charge. Par exemple, vous pouvez utiliser Composer :

composer create-project laravel/laravel my-api-platform-laravel-app
cd my-api-platform-laravel-app
#

Installer API Platform

Dans votre projet, installez l'intégration API Platform pour Laravel :

composer require api-platform/laravel

Ensuite,  publiez ses ressources et sa configuration :

php artisan api-platform:install

Si ce n'est pas déjà fait, démarrez le serveur web intégré :

php artisan serve

Rendez-vous à l’adresse http://127.0.0.1:8000/api/ : votre API est déjà active et documentée... mais pour le moment, elle est vide !

Capture d'écran d'API Platform en local" class="wp-image-10261#

Créer un modèle Eloquent

Pour découvrir le fonctionnement d’API Platform, nous allons créer une API permettant de  gérer une librairie. Commençons par créer un modèle Book :

php artisan make:model Book

Par défaut, Laravel utilise SQLite. Vous pouvez ouvrir le fichier database/database.sqlite avec votre client SQLite préféré (PhpStorm fonctionne à merveille), créer une table nommée books, et ajouter quelques colonnes ; Eloquent et API Platform détecteront ces colonnes automatiquement. Il existe une meilleure alternative : l'utilisation d'une classe de migration.

#
Créer une migration

Tout d'abord, créez une classe de migration pour la table books :

php artisan make:migration create_books_table

Ouvrez la classe de migration générée (database/migrations/<timestamp>_create_books_table.php) et ajoutez des colonnes :

    public function up(): void
    {
        Schema::create('books', function (Blueprint $table) {
            $table->id();

            $table->string('isbn')->nullable();
            $table->string('title');
            $table->text('description');
            $table->string('author');
            $table->date('publication_date')->nullable();

            $table->timestamps();
        });
    }

Enfin, exécutez la migration :

php artisan migrate

La table et les colonnes ont été créées !

#

Exposer un modèle

Ouvrez le fichier app/Models/Book.php que nous avons généré à l'étape précédente et ajoutez l'attribut #[ApiResource] sur la classe qu’il contient :

namespace App\Models;

use ApiPlatform\Metadata\ApiResource;
use Illuminate\Database\Eloquent\Model;

#[ApiResource]
class Book extends Model
{
}

Retournez à l'adresse http://127.0.0.1:8000/api/, actualisez la page : tadam, votre API est disponible et entièrement fonctionnelle 🎉 !Basic REST API

Vous pouvez jouer avec votre API grâce à la sandbox fournie par SwaggerUI. Sous le capot, API Platform :

  • A enregistré des routes REST standard dans le routeur de Laravel et un contrôleur qui expose un endpoint d'API complet et sécurisé, en utilisant les services fournis par la bibliothèque API Platform Core.
  • A utilisé le state provider d’Eloquent pour explorer la base de données et collecter des métadonnées sur toutes les colonnes à exposer dans l'API
  • A généré des documentations de l'API lisibles par des machines dans les formats OpenAPI (anciennement connu sous le nom de Swagger (disponibles à http://127.0.0.1:8000/api/docs.json) et JSON-LD/Hydra à l'aide de ces métadonnées
  • A généré une documentation agréable et lisible par des êtres humaines ainsi qu’une sandbox pour l'API avec SwaggerUI (Redoc est également disponible prêt à l'emploi)
  • Imaginez maintenant devoir à nouveau faire tout ça à la main ? Combien de temps avez-vous gagné ? Des semaines, des mois ? Et vous n'avez encore rien vu !
#

Jouer avec l'API

Si vous accédez à une URL d'API en ajoutant l'extension .html, API Platform affichera la requête d'API correspondante dans l'interface utilisateur. Essayez par vous-même en vous rendant à l'adresse http://127.0.0.1:8000/api/books.html. Si aucune extension n'est présente, API Platform utilisera l'en-tête Accept pour sélectionner le format à utiliser.

Ainsi, si vous souhaitez accéder aux données brutes, vous avez deux possibilités :

  • Ajouter un en-tête Accept correct (ou ne définissez pas d'en-tête Accept du tout si vous ne vous souciez pas de la sécurité) - ce qui est préférable lorsque vous écrivez des clients API.
  • Ajouter le format que vous souhaitez comme extension de la ressource - à des fins de débogage uniquement.

Par exemple, allez à http://127.0.0.1:8000/api/books.jsonld pour récupérer la liste des ressources Book au format JSON-LD.

Bien entendu, vous pouvez également utiliser votre client HTTP préféré pour interroger l'API. Nous aimons beaucoup Hoppscotch, un client API libre et gratuit qui prend bien en charge API Platform.

#

Utilisation de DTO et intégration de logique personnalisée

Exposer directement des données de la base de données est pratique pour le développement rapide d'applications, mais utiliser différentes classes pour les données internes et les données publiques est une bonne pratique pour des projets plus complexes.

Comme expliqué dans nos considérations générales en matière de conception, API Platform permet d'utiliser la source de données de notre choix grâce à un provider, et les Data Transfer Objects (DTO) sont des first-class citizens !

Créons notre DTO : 

<?php

namespace App\ApiResource;

use ApiPlatform\Metadata\Get;

#[Get(uriTemplate: '/my_custom_book/{id}')]
class Book
{
    public string $id;
    public string $title;
}

et déclarons notre nouveau répertoire dans API Platform :

// config/api-platform.php

// ...
return [
    'resources' => [
        app_path('ApiResource'),
        app_path('Models'),
    ],

    // ...
];

Ensuite, nous pouvons créer la logique pour récupérer l'état de notre DTO book :

<?php

namespace App\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Models\Book as BookModel;

final class BookProvider implements ProviderInterface
{
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
    {
        $book = BookModel::find($uriVariables['id']);
        return new Book(id: $book->id, title: $book->title);
    }
}

Enregistrez le state provider : 

<?php

namespace App\Providers;

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\ServiceProvider;

class ApiServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(BookProvider::class, function (Application $app) {
            return new BookProvider();
        });

        $this->app->tag([BookProvider::class], ProviderInterface::class);
    }
}

Déclarez le provider sur votre opération : 

<?php

namespace App\ApiResource;

use ApiPlatform\Metadata\Get;
use App\State\BookProvider;

#[Get(uriTemplate: '/my_custom_book/{id}', provider: BookProvider::class)]
class Book
{
    public string $id;
    public string $title;
}
#

Négociation de contenu

Par défaut, une réponse JSON-LD est envoyée mais de nombreux autres formats, y compris CSV et JSON:API sont pris en charge. Vous pouvez activer ou désactiver les formats dans config/api-platform.php :

// config/api-platform.php

// ...
return [
    'formats' => [
        'jsonld' => ['application/ld+json'],
        'jsonapi' => ['application/vnd.api+json'],
        'csv' => ['text/csv'],
    ],

    'patch_formats' => [
        'json' => ['application/merge-patch+json'],
    ],

    'docs_formats' => [
        'jsonld' => ['application/ld+json'],
        'jsonapi' => ['application/vnd.api+json'],
        'jsonopenapi' => ['application/vnd.openapi+json'],
        'html' => ['text/html'],
    ],

    // ...
];
#

Activation de GraphQL

GraphQL in Laravel

Par défaut, seuls les endpoints REST sont activés, mais API Platform supporte également GraphQL !

Installez le paquet GraphQL :

composer require api-platform/graphql:^4

Activez-le dans le fichier config/api-platform.php :

'graphql' => [
-        'enabled' => false,
+        'enabled' => true,

Enfin, ouvrez http://127.0.0.1:8000/api/graphql et remplacez l'exemple de requête GraphQL par défaut par la requête suivante :

{
  books(first: 3) {
    edges {
      node {
        title
        author
        publicationDate
      }
    }
  }
}

Vous avez désormais une API REST et une API GraphQL avec le même code ! Comme vous pouvez le constater, une belle UI (GraphiQL) est également disponible. La documentation est automatiquement générée à l'aide du endpoint d'introspection GraphQL.

#

Masquer des champs

API Platform permet de contrôler quels champs seront exposés publiquement par l'API en utilisant la même syntaxe que la sérialisation Eloquent :

namespace App\Models;

use ApiPlatform\Metadata\ApiResource;
use Illuminate\Database\Eloquent\Model;

#[ApiResource]
class Book extends Model
{
    /**
     * The attributes that should be hidden (deny list).
     *
     * @var array
     */
    protected $hidden = ['isbn'];
}
namespace App\Models;

use ApiPlatform\Metadata\ApiResource;
use Illuminate\Database\Eloquent\Model;

#[ApiResource]
class Book extends Model
{
    /**
     * The attributes that should be visible (allow list).
     *
     * @var array
     */
    protected $visible = ['title', 'description'];
}
#

Relations et ressources imbriquées

Remplaçons notre colonne auteur par une relation avec une nouvelle table author :

public function up(): void
    {
        Schema::create('books', function (Blueprint $table) {
            $table->id();

            $table->string('description');
-            $table->string('author');
+            $table->integer('author_id')->unsigned();
+            $table->foreign('author_id')->references('id')->on('authors');

            $table->timestamps();
        });

+       Schema::create('authors', function (Blueprint $table): void {
+           $table->id();
+           $table->string('name');
+           $table->timestamps();
+       });
    }

Ce faisant, API Platform gérera automatiquement les liens vers cette relation en utilisant votre format préféré (JSON:API, JSON-LD, etc.) et lorsque nous demandons un Book, nous obtenons désormais :

{
  "@context": "/api/contexts/Book",
  "@id": "/api/books/1",
  "@type": "Book",
  "name": "Miss Nikki Senger V",
  "isbn": "9784291624633",
  "publicationDate": "1971-09-04",
  "author": "/api/authors/1"
}

Pour créer un Book lié à un Author, vous devez utiliser des IRI pour référencer la relation :

PATCH /api/books/1
Content-Type: application/merge-patch+json

{
    "author": "/api/authors/2"
}

Il existe un mécanisme puissant à l'intérieur d’API Platform pour créer des routes en utilisant des relations (par exemple : /api/auteurs/2/livres). Vous obtiendrez plus de détails sur les sous-ressources ici.

#

Pagination des données

La pagination est une fonctionnalité indispensable pour les APIs, sans elle, les réponses de collection deviennent rapidement énormes, lentes, et peuvent même entraîner des plantages (erreurs de mémoire, timeouts...).

Heureusement, le state provider d’Eloquent, fourni par API Platform, effectue automatiquement la pagination des données !

Pour tester cette fonctionnalité, injectons des données fictives dans la base de données.

#
Alimenter la base de données

Au lieu de créer manuellement les données dont vous avez besoin pour tester votre API, il peut être pratique d'insérer automatiquement de fausses données dans la base de données.

Laravel fournit un moyen pratique de le faire : Eloquent Factories. Commençons par créer une classe factory pour notre modèle Book :

php artisan make:factory BookFactory

Ensuite, modifiez database/factories/BookFactory.php pour spécifier le générateur à utiliser pour chaque propriété du modèle :

namespace Database\Factories;

 use Illuminate\Database\Eloquent\Factories\Factory;

 /**
  * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Book>
  */
 class BookFactory extends Factory
 {
     /**
      * Define the model's default state.
      *
      * @return array<string, mixed>
      */
     public function definition(): array
     {
         return [
-            //
+            'title' => mb_convert_case(fake()->words(4, true), MB_CASE_TITLE),
+            'isbn' => fake()->isbn13(),
+            'description' => fake()->text(),
+            'author' => fake()->name(),
+            'publication_date' => fake()->date(),
         ];
     }
 }

Mettez à jour l'app/Models/Book.php pour indiquer à Eloquent que ce modèle possède une classe factory associée :

namespace App\Models;
 
 use ApiPlatform\Metadata\ApiResource;
+use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 
 #[ApiResource]
 class Book extends Model
 {
+    use HasFactory;
 }

Faites référence à cette factory dans le seeder (database/seeder/DatabaseSeeder.php) :

namespace Database\Seeders;

+use App\Models\Book;
 use App\Models\User;
 // use Illuminate\Database\Console\Seeds\WithoutModelEvents;
 use Illuminate\Database\Seeder;

 class DatabaseSeeder extends Seeder
 {
     /**
      * Seed the application's database.
      */
     public function run(): void
     {
         // User::factory(10)->create();

         User::factory()->create([
             'name' => 'Test User',
             'email' => 'test@example.com',
         ]);

+        Book::factory(100)->create();
     }
 }

Enfin, remplissez la base de données avec :

php artisan db:seed
#
Configuration de la pagination

Envoyez une requête GET sur http://127.0.0.1:8000/api/books.

Par défaut, API Platform pagine les collections par paquets de 30 éléments, cette valeur est configurable. Pour passer à 10 éléments par page, modifiez app/Models/Book.php comme ceci :

namespace App\Models;
 
 use ApiPlatform\Metadata\ApiResource;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 
-#[ApiResource]
+#[ApiResource(
+    paginationItemsPerPage: 10,
+)]
 class Book extends Model
 {
     use HasFactory;
 }

Consultez la documentation de la pagination pour savoir tout ce que vous pouvez faire !

#

Personnalisation de l’API

API Platform dispose d'un grand nombre de paramètres et vous donne un contrôle total sur ce qui est exposé.Par exemple, voici comment rendre votre API en lecture seule en activant uniquement les opérations GET :

 // app/Models/Book.php
 namespace App\Models;

+use ApiPlatform\Metadata\Get;
+use ApiPlatform\Metadata\GetCollection;
 use Illuminate\Database\Eloquent\Model;

-#[ApiResource]
 #[ApiResource(
     paginationItemsPerPage: 10,
+    operations: [
+        new GetCollection(),
+        new Get(),
+    ],
 )]
 class Book extends Model
 {
 }

Nous utiliserons les options de configuration fournies par API Platform tout au long de cet article, mais il existe des tonnes de fonctionnalités !

Un bon moyen de les découvrir est d'inspecter les propriétés des attributs ApiResource et ApiProperty et, bien sûr, de lire la documentation.

Vous pouvez modifier la configuration par défaut (par exemple, quelles opérations sont activées par défaut) dans le fichier config/api-platform.php.

Pour le reste de cet article, nous supposerons qu'au moins toutes les opérations par défaut sont activées (vous pouvez également activer PUT si vous souhaitez prendre en charge les opérations d'insertion).

#

Ajouter des filtres

API Platform fournit un raccourci facile vers certains filtres utiles. Pour commencer, vous pouvez activer un PartialSearchFilter sur la propriété title :

// app/Models/Book.php
 namespace App\Models;

 use ApiPlatform\Metadata\ApiResource;
+use ApiPlatform\Laravel\Eloquent\Filter\PartialSearchFilter;
 use Illuminate\Database\Eloquent\Model;

 #[ApiResource]
+#[QueryParameter(key: 'title', filter: PartialSearchFilter::class)]
 class Book extends Model
 {
 }

Il est également possible d'activer des filtres sur chaque propriété exposée :

// app/Models/Book.php
 namespace App\Models;

 use ApiPlatform\Metadata\ApiResource;
+use ApiPlatform\Laravel\Eloquent\Filter\PartialSearchFilter;
+use ApiPlatform\Laravel\Eloquent\Filter\OrderFilter;
 use Illuminate\Database\Eloquent\Model;

 #[ApiResource]
+#[QueryParameter(key: ':property', filter: PartialSearchFilter::class)]
+#[QueryParameter(key: 'sort[:property]', filter: OrderFilter::class)]
 class Book extends Model
 {
 }

Le OrderFilter permet de trier la collection. Le placeholder :property permet de créer un paramètre pour chaque propriété exposée, et ces filtres sont automatiquement documentés :

Filters documentation

En outre, certaines règles de validation sont automatiquement ajoutées sur la base du schéma JSON donné. Vous pouvez personnaliser l'ensemble des règles via l'option constraints d'un QueryParameter.

API Platform propose plusieurs filtres dédiés à Laravel, plus d'informations sur cette page !

#

Authentication

API Platform se repose sur le mécanisme natif d'authentification de Laravel.

Il prend également en charge de manière native :

  • Laravel Sanctum, un système d'authentification pour les SPA (Single Page Application), les applications mobiles et les API simplement basées sur des tokens.
  • Laravel Passport, un serveur OAuth 2 complet.
  • Laravel Socialite, des fournisseurs OAuth incluant Facebook, X, LinkedIn, Google, GitHub, GitLab, Bitbucket et Slack.
#
Se connecter avec Swagger UI

Dans Swagger UI, vous pouvez authentifier vos requêtes en utilisant le bouton Authorize dans le coin supérieur droit, moyennant quelques configurations à ajouter dans le fichier config/api-platform.php.

Voici un exemple de configuration de l'authentification par clé API :

// config/api-platform.php
'swagger_ui' => [
    'enabled' => true,
    'apiKeys' => [
        'api' => [
            'type' => 'header',
            'name' => 'X-API-Key'
        ]
    ]
]

Ou si vous utilisez Laravel Passport (ou tout autre serveur OAuth) :

// config/api-platform.php
'swagger_ui' => [
    'enabled' => true,
    'oauth' => [
        'enabled' => true,
        'type' => 'oauth2',
        'flow' => 'authorizationCode',
        'tokenUrl' => '<oauth_token_endpoint>',
        'authorizationUrl' =>'<oauth_authorization_endpoint>',
        'refreshUrl' => '<oauth_refresh_endpoint>',
        'scopes' => ['scope' => 'Description of the scope'],
        'pkce' => true,
    ]
]

Une combinaison des deux est également possible. Pour plus d'informations, vous pouvez également consulter la documentation Swagger UI.

#
Middlewares

Il est parfois pratique d'imposer l'utilisation d'un middleware pour toutes les routes API.

L'exemple suivant montre comment activer le middleware Laravel Sanctum sur toutes les routes de notre API : 

// config/api-platform.php
return [
    // ..
    'defaults' => [
        'middleware' => 'auth:sanctum',
    ],
];
#

Autorisation et validation des opérations d'écriture

Pour autoriser les opérations d'écriture (POST, PATCH, PUT) et valider les saisies des utilisateurs, vous pouvez générer une classe Form Request :

php artisan make:request BookFormRequest

Ensuite, ajoutez des règles de validation à la classe générée (app/Http/Requests/BookFormRequest.php dans notre exemple) :

 namespace App\Http\Requests;

 use Illuminate\Foundation\Http\FormRequest;

 class BookFormRequest extends FormRequest
 {
     /**
      * Determine if the user is authorized to make this request.
      */
     public function authorize(): bool
     {
-        return false;
+        return user()->isAdmin();
     }
 
     /**
      * Get the validation rules that apply to the request.
      *
      * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
      */
     public function rules(): array
     {
         return [
-             //
+            'title' => 'required|unique:books|max:255',
+            'description' => 'required',
+            'author' => 'required|max:100',
         ];
     }
 }

Dans cet exemple, nous autorisons uniquement les utilisateurs administrateurs à effectuer des opérations d'écriture, et nous ajoutons quelques règles de validation.

Si les conventions standard de Laravel sont respectées, la classe Form Request est automatiquement détectée et utilisée. Dans le cas contraire, il faut la référencer explicitement via le paramètre rules :

 // app/Models/Book.php
 namespace App\Models;

+use App\Http\Requests\BookFormRequest;
 use Illuminate\Database\Eloquent\Model;

-#[ApiResource]
+#[ApiResource(
+    rules: BookFormRequest::class,
+)]
 class Book extends Model
 {
 }

API Platform transformera toute exception dans le format RFC 7807 (Problem Details for HTTP APIs). Vous pouvez créer votre propre ressource Error en suivant ce guide.

Pour aller plus loin, pour pouvez également lire la documentation dédiée à la validation des données avec Laravel.

#

Autorisation

Pour protéger une opération et faire en sorte que seuls les utilisateurs autorisés puissent y accéder, commencez par créer une Laravel policy :

php artisan make:policy BookPolicy --model=Book

Laravel détectera automatiquement votre nouvelle policy et l'utilisera lors de la manipulation d'un Book.

Là encore, pour approfondir le sujet, vous pouvez lire la documentation dédiée.

#

Utilisation des outils JavaScript

Ne serait-il pas intéressant de disposer d'un backend d'administration pour gérer les données exposées par votre API ? Rendez-vous sur API Platform Admin !

The admin

Cet admin utilisant Material Design est une SPA construite avec React Admin, puissant et entièrement personnalisable. Il s'appuie sur la documentation Hydra exposée par le composant API,  c'est 100 % dynamique : aucune génération de code n'a lieu.

#
Mise en place d’une SPA/PWA

API Platform dispose également d'un générateur de client capable de créer des Progressive Web Apps / Single Page Apps entièrement fonctionnelles avec Next.js, Nuxt.js, React/Redux, Vue.js, Quasar, et Vuetify, que vous pouvez facilement ajuster et personnaliser. Le générateur prend également en charge React Native si vous préférez exploiter toutes les capacités des appareils mobiles.

Le code généré contient une liste (avec pagination), un bouton de suppression, un formulaire de création et un formulaire de modification. Il inclut également Tailwind CSS classes et ARIA roles pour rendre l'application accessibles à tous les publics. Consultez la documentation dédiée.

#

Mise en cache

API Platform s’occupe par défaut de la mise en cache des métadonnées en utilisant le système de cache de Laravel pour stocker ces informations. La mise en cache est automatiquement activée dans les environnements de production (lorsque APP_DEBUG est défini sur false).

L'appel de php artisan optimize mettra en cache les métadonnées et améliorera considérablement les performances de votre API.

Pour vider le cache, utilisez php artisan optimize:clear.

#

Intégration de votre propre logique métier

Maintenant que vous avez appris les bases, assurez-vous de lire les considérations de conception générale et comment étendre API Platform pour comprendre comment le framework est conçu, et comment intégrer votre propre logique métier.

#

Utiliser le IsApiResourceTrait au lieu des attributs

Bien que les attributs (introduits par PHP 8) soient la méthode préférée pour configurer les ressources d’API Platform, il est également possible d'utiliser un trait à la place.

Ces deux classes sont strictement équivalentes :

// Attributes
namespace App\Models;

use ApiPlatform\Metadata\ApiResource;
use Illuminate\Database\Eloquent\Model;

#[ApiResource]
class Book extends Model
{
}
// Trait
namespace App\Models;

use ApiPlatform\Metadata\IsApiResource;
use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    use IsApiResource;
}

Lorsque l'on utilise le IsApiResourceTrait, il est également possible de renvoyer une configuration avancée en définissant une méthode statique apiResource().

Ces deux classes sont strictement équivalentes :

// Attributes
namespace App\Models;

use ApiPlatform\Metadata\ApiResource;
use Illuminate\Database\Eloquent\Model;

#[ApiResource(
    paginationItemsPerPage: 10,
    operations: [
       new GetCollection(),
       new Get(),
    ],
)]
class Book extends Model
{
}
// Trait
namespace App\Models;

use ApiPlatform\Metadata\IsApiResource;
use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    use IsApiResource;

    public static function apiResource(): ApiResource
    {
        return new ApiResource(
            paginationItemsPerPage: 10,
            operations: [
                new GetCollection(),
                new Get(),
            ],
        );
    }
}

Il est assez courant de définir plusieurs attributs ApiResource, ApiProperty et Filter sur la même classe. Pour imiter ce comportement, la fonction apiResource() peut renvoyer un tableau au lieu d'une instance unique de la classe de métadonnées. Ces deux classes sont strictement équivalentes :

// Attributes
namespace App\Models;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\QueryParameter;
use ApiPlatform\Laravel\Eloquent\Filter\PartialSearchFilter;
use App\Http\Requests\BookFormRequest;
use Illuminate\Database\Eloquent\Model;

#[ApiResource(
    paginationEnabled: true,
    paginationItemsPerPage: 5,
    rules: BookFormRequest::class,
    operations: [
        new Put(),
        new Patch(),
        new Get(),
        new Post(),
        new Delete(),
        new GetCollection(),
    ]
)]
#[QueryParameter(key: ':property', filter: PartialSearchFilter::class)]
class Book extends Model
{
}
// Trait
namespace App\Models;

use ApiPlatform\Metadata\IsApiResource;
use ApiPlatform\Metadata\QueryParameter;
use ApiPlatform\Laravel\Eloquent\Filter\PartialSearchFilter;
use App\Http\Requests\BookFormRequest;
use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    use IsApiResource;

    public static function apiResource(): array
    {
        return [
            new ApiResource(
                paginationEnabled: true,
                paginationItemsPerPage: 5,
                rules: BookFormRequest::class,
                operations: [
                    new Put(),
                    new Patch(),
                    new Get(),
                    new Post(),
                    new Delete(),
                    new GetCollection(),
                ]
            ),
            new QueryParameter(key: ':property', filter: PartialSearchFilter::class),
        ];
    }
}
#

À vous de jouer !

Ainsi se dessine l’éventail des possibilités pour concevoir un projet avec API Platform et Laravel. Que vous soyez novice ou dev expérimenté·e, l'ajout de ce support ouvre de nouvelles perspectives et offre un terrain de jeu idéal pour créer des applications robustes, évolutives, et bâties sur des technologies de pointe. Que pensez-vous d'API Platform pour Laravel ? N’hésitez pas à nous faire part de vos retours sur les réseaux, à signaler des éventuels disfonctionnements, à laisser une étoile sur GitHub pour soutenir le projet et l'équipe contributrice. Encore mieux, dites-nous si vous avez mis en place un projet à l'aide de la fusion de ces deux frameworks ! Nous espérons que ce tutoriel vous a plu, si vous avez tenu jusqu'à la fin de ce post, nous vous félicitons et en profitons pour vous annoncer que le replay de la keynote de Kévin sera disponible sur notre chaîne YouTube dès le vendredi 8 novembre.

Le blog

Pour aller plus loin