Usage
laravel-arkitect (aka Arkitect) est une surcouche dogmatique du package phparkitect/arkitect offrant tout un lot de règles spécifiques à Laravel pour vérifier la structure de nos projets.
Contrairement à Laravel Pint, que nous avons vu récemment, Arkitect se concentre sur l’architecture de votre projet en vérifiant que vos class se trouvent au bon endroit, avec le bon naming, la bonne interface, le bon héritage …
1composer require mortexa/laravel-arkitect --dev
Une fois le package installé, vous pouvez tout de suite lancer votre première analyse avec la commande suivante :
1php artisan test:arkitect
Arkitect analysera votre code à l’aide de ses règles par défaut, ses dernières correspondent aux standards qu’applique la core team de Laravel pour ses projets.
1NO VIOLATIONS DETECTED!2Execution time: 0.46s
Désormais, introduisons volontairement une erreur dans notre code, par exemple, un controller dans Laravel doit hériter de la class App\Http\Controllers\Controller
, si nous supprimons cet héritage dans l’un de nos controllers.
1class HomeController2{3 [...]
En relançant l’analyse, Arkitect détectera une violation de ses règles.
1ERRORS!2 3App\Http\Controllers\HomeController has 1 violations4 should extend App\Http\Controllers\Controller5 because we use Laravel framework!6 71 VIOLATIONS DETECTED!8Execution time: 0.49s
Configurer les règles
Les règles par défaut de Arkitect peuvent s’avérer contraignantes et ne pas correspondre à vos standards de code, dans ce cas, il est possible de publier la configuration des règles avec la commande suivante :
1php artisan vendor:publish --provider="Mortexa\LaravelArkitect\ArkitectServiceProvider" --tag="config"
Vous pourrez dès lors configurer les règles d'analyse du package depuis le fichier config/arkitect.php
!
Les règles customisées
La véritable force de Arkitect ne réside pas dans sa configuration par défaut mais dans la possibilité de créer nos propres règles !
Le package dispose d'une commande make
facilitant l'ajout d'une nouvelle règle.
1php artisan make:arkitect {name}
Une règle custom se décompose comme suit :
1<?php 2 3namespace Tests\Architecture; 4 5use Arkitect\Rules\DSL\ArchRule; 6use Mortexa\LaravelArkitect\Contracts\RuleContract; 7use Mortexa\LaravelArkitect\Rules\BaseRule; 8 9class CustomRule extends BaseRule implements RuleContract10{11 /**12 * Define your architectural rule13 */14 public static function rule(): ArchRule15 {16 //17 }18 19 /**20 * Define the path related to your rule21 */22 public static function path(): string23 {24 //25 }26}
La méthode path
détermine le, ou les dossiers, ou la règle prendra effet tandis que la méthode rules
retournera une instance de RuleContract
contenant la logique de validation.
Voyons désormais un cas concret d'utilisation d'une règle custom !
Cas concret d'une règle customisée
Nous vous présentions il y a quelque temps la mise en place d'une architecture modulaire dans une application Laravel.
Dans cette application, nous avons décidé que les modules ne devaient pas communiquer entre eux, qu'ils devaient être isolés afin d'éviter les interdépendances.
1app/2 Modules/3 Blog/4 Workspace/
Le module Blog ne doit pas avoir connaissance du module Workspace ni se partager des services ou des fonctionnalités, Arkitect est en mesure de nous aider à appliquer cette contrainte grace à une règle custom !
Commençons par créer une nouvelle règle depuis la commande make
:
1php artisan make:arkitect BlogModuleIsIsolated
Notre règle arrivera dans le fichier tests/Architecture/BlogModuleIsIsolated
à coté de vos tests, nous pouvons désormais la compléter à l'aide de quelques conditions.
1<?php 2 3namespace Tests\Architecture; 4 5use Arkitect\Rules\Rule; 6use Arkitect\Rules\DSL\ArchRule; 7use Mortexa\LaravelArkitect\Rules\BaseRule; 8use Mortexa\LaravelArkitect\Contracts\RuleContract; 9use Arkitect\Expression\ForClasses\ResideInOneOfTheseNamespaces;10use Arkitect\Expression\ForClasses\NotHaveDependencyOutsideNamespace;11 12class BlogModuleIsIsolated extends BaseRule implements RuleContract13{14 /**15 * Define your architectural rule16 */17 public static function rule(): ArchRule18 {19 return Rule::allClasses()20 ->that(new ResideInOneOfTheseNamespaces('App\Modules\Blog'))21 ->should(new NotHaveDependencyOutsideNamespace('App\Modules\Blog'))22 ->because('The blog module must be isolated.');23 }24 25 /**26 * Define the path related to your rule27 */28 public static function path(): string29 {30 return 'app/Modules/Blog';31 }32}
Le fichier de test ainsi obtenu est relativement explicite.
Toutes les classes du dossier app/Modules/Blog
ayant le namespace App\Modules\Blog
ne doivent pas utiliser de class provenant d'un autre namespace.
Le package propose énormément de condition pour créer vos propres règles custom, que ce soit à propos du nommage, l'héritage, les interfaces, les namespaces ... Vous trouverez l'ensemble des conditions disponibles à cette URL.
Conclusion
Arkitect est un outil simple à prendre à main et offrira, à l'instar de Pint, une première approche penless des tests architecture dans vos projets Laravel.
A lire
Autres articles de la même catégorie
Des mocks avec Prophecy
Prophecy est un package permettant de créer des puissants et flexibles mock dans vos tests.
Mathieu De Gracia
Améliorer le référencement avec spatie/laravel-sitemap
Voyons ensemble comment créer un sitemap afin d'optimiser le référencement auprès des moteurs de recherche !
Antoine Benevaut
Type-Safe de A à Z
Unifiez les types entre le backend et le frontend pour réduire les bugs et améliorer la cohérence de votre code
Rémy Guillermic