Laravel – Livewire

Auteur(s) de l'article

Un article écrit par un développeur back-end. Simple à comprendre et à mettre en place.
Le projet est disponible sur mon GitHub.

Préambule

Laravel est un framework tout comme Symfony. Une structure qui nous aide, nous, développeurs à créer des contenus toujours plus poussés, motivants et complets sans pour autant réinventer la roue à chaque projet.
La différence entre Symfony et Laravel ? Cela dépend des goûts et des préférences de chaque développeur et de ses expériences passées. Pour ma part, je suis pour Laravel, je préfère la syntaxe et "l'élégance" de cette plateforme et la polyvalence des fonctionnalités présentes "out of the box", comme par exemple, la gestion des queues.
Aujourd'hui, je vais me concentrer sur une fonctionnalité toute particulière, plus ou moins similaire à Symfony UX Live Components mais moins experimentale.

Livewire

Ceci est une partie assez récente de Laravel. Elle est sortie il y a environ 3 ans à l'heure où j'écris cet article.
Livewire permet de construire une application web moderne complexe, tout en réduisant la difficulté pour un développeur back-end de gérer le front-end.
C'est un peu comme un framework dans Laravel. On a ainsi la possibilité de construire des interfaces dynamiques et simples tout en gardant le confort de la syntaxe de Laravel.

Let's go?

Je commence d'abord par créer mon environnement de développement avec l'aide de notre très cher Docker.
Je travaille avec :
  • Laravel: 9.7.X
  • Livewire: 2.10.5
  • PHP: 8.1.4
  • Postgress: 14

Dockerfile

Tout ce qui a de plus classique.
Disponible ici.

Bootstrap

Après avoir « bootstrapé » le project grâce à l'aide de composer (composer create-project laravel/laravel example-app), nous pouvons directement suivre Docker avec un joli docker-compose up -d et se rendre à la machine à café ☕️.

Ensuite http://localhost:8080 est disponible !
Le reste est globalement de la config; vous pouvez copier le .env.example en .env.
On continue avec Laravel Jetstram, un starter-kit pour Laravel, qui nous permet d'avoir, en un claquement de doigts, utilisateurs, logins, 2FA, session managements, API et/ou team management.
composer require laravel/jetstream
php artisan jetstream:install livewire # --teams
docker-compose exec app php artisan migrate
npm i && npm run dev
Ces 4 commandes nous permettent de:
  1. Installer Jetstream.
  2. Demander à avoir Livewire.
    1. Passer un argument --teams si vous souhaitez avoir la gestion d'équipes.
  3. Faire les migrations sur la base de données.
  4. Installer les dépendances front-end.
Et voilà 🎉, un Laravel tout beau tout neuf.

Créons notre premier composant !

Le routing

Le routing : une partie essentielle quand on parle de cutting-edge web framework.
Ici, c'est plutôt simple, les routes se trouvent dans routing/web.php et sont très faciles à déclarer. Faisons-en une pour notre démo avec un Controller.
Dans notre exemple, rendons nous dans l'URI /demo.
Au début, ce n'est qu'une simple page blanche.

Le composant Livewire

Nous voici dans le vif du sujet ! Créons un composant.
Selon la documentation, la commande est simple: php artisan make:livewire <nom>.
Faisons le composant Antistatique.
On se retrouve avec un composant tout bête pour l'instant avec un template.
Il s'agit là d'un simple composant qui étend Livewire. Nous allons commencer à travailler dessus très rapidement.
Voici donc le template.
Amusons-nous maintenant avec le framework.
Depuis un template quelconque, on peut donc appeler notre composant livewire comme un composant VueJS !
Il suffit d'ajouter <livewire:le-nom-du-composant /> , et Blade (le moteur de rendu) se charge du reste.

Après quelques modifications du template de base demo.index ainsi que du template livewire.antistatique, on arrive à un résultat.

Where the fun begins

Souvenez-vous de note class de base, \App\Http\Livewire\Antistatique, cette dernière étant une class, on peut y faire ce qu'on veut.
Ajoutons une propriété int $loveCounter.
Notre class devrait ressembler à ceci.
::showLove et $loveCounter sont des éléments avec lesquels le front-end peut intéragir via AlpineJS (tout est déjà fourni !).
Dans le template, il suffit d'ajouter sur un bouton <button wire:click=showLove">+</button>.
Une fois le composant mis en place, il ressemble à ceci:
<div>
    <div class="alert alert-info shadow-lg">
        <div>
            <i class="fa-solid fa-circle-info"></i>
            <span>Bonjour, je suis un composant Livewire!</span>
        </div>
    </div>
    <div class="mt-10">
        <div class="card bg-base-100 w-60 max-w-[65em] shadow-2xl inner-shadow m-auto">
            <div class="card-body">
                <div class="flex gap-6">
                    <div>
                        <span class="countdown font-mono text-9xl">
                            <span style="--value:{{ $loveCounter }}"></span>
                        </span>
                        <span class="font-bold text-2xl">
                            Love for Antistatique 💘
                        </span>
                    </div>
                </div>
                <div class="card-actions justify-end">
                    @if(!$shouldReturnToZero)
                        <button wire:click="showLove" class="btn btn-block btn-accent mt-5">Ajouter de l'amour</button>
                    @else
                        <button wire:click="removeLove" class="btn btn-block btn-accent mt-5">Retirer de l'amour</button>
                    @endif
                </div>
            </div>
        </div>
    </div>
</div>
Tout se sittue au niveau du back-end et ainsi, AlpineJS discutent entre eux ainsi qu'avec Blade qui fait la liaison initiale.

Tout ceci est bien entendu SEO friendly car la page est générée intialement comme n'importe quelle page.
Voici le résultat !

Comment cela fonctionne et quelles sont les possibilités ?

Livewire est rendu initialement comme n'importe quelle page Blade. Ensuite, quand une interraction est demandée, en l'occurence comme notre wire:click, Livewire génère une requête AJAX au back-end qui met à jour les données puis le composant. Ce dernier est ensuite renvoyé au front-end.
Le DOM est manipulé intelligement et ne change que les éléments du composant.

Les possibilités sont quasiment ilimitées et il faudrait plusieurs articles pour en parler dans les détails. Tout ceci étant branché à l'écosystème de Laravel !

Autre élément qui me permet de prétendre ceci : Livewire possède également les Hooks de lifecyle.
Livewire se comporte de façon Stateless, cela veut dire qu'il n'y a pas d'instance de Livewire qui vit sur le serveur et qui attend une interraction client.

Voici une petite image prise de la documentation de Livewire qui nous explique comment tout cela fonctionne.
Source: https://laravel-livewire.com/docs/2.x/security

Et la sécurité ?

Comme tout composant front-end, les données se situent chez le client. Il est donc possible d'avoir une manipulation d'une personne mal intentionnée, et il est donc primordial d'avoir de la validation et/ou des contre-mesures adéquates en fonction de l'implication des données (en l'occurence ce n’est pas nécessaire pour un compteur).

Néamoins, Livewire passe des checksums entre chaques requêtes, si ces dernières ne sont pas valides, la requête ne sera pas lancée.

Si vous souhaitez en savoir plus sur la sécurité, je vous laisse vous rendre sur cette page.

Le mot de la fin.

J'espère avoir réussi à captiver votre attention. N'hésitez pas à aller regarder le projet démo sur mon repository et à jouer avec !

Livewire est un concept vraiment intéressant d'un point de vue de développeur back-end, permettant de générer des composants en PHP sans avoir à créer des API dédiées, ainsi que des controllers / routings.

Livewire permet de valider les éléments comme le texte, un email ou pleins d'autres choses (comme dans Laravel). Vous pouvez aussi l'utiliser pour des envois de fichiers, l’attacher à plein d’évènements d'actions comme des Clicks, Keydown ou Submit ou pour émettre des events pour des listeners, ...
En soit, c'est un micro-framework qui à une place très importante dans Laravel et nous permet d'intéragir avec notre application et tout son écosystème autour.
Merci de m'avoir lu !