Laravel Arkitect

Publié le 15 novembre 2022 par Mathieu De Gracia
Couverture de l'article Laravel Arkitect

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 HomeController
2{
3 [...]

En relançant l’analyse, Arkitect détectera une violation de ses règles.

1ERRORS!
2 
3App\Http\Controllers\HomeController has 1 violations
4 should extend App\Http\Controllers\Controller
5 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 RuleContract
10{
11 /**
12 * Define your architectural rule
13 */
14 public static function rule(): ArchRule
15 {
16 //
17 }
18 
19 /**
20 * Define the path related to your rule
21 */
22 public static function path(): string
23 {
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 RuleContract
13{
14 /**
15 * Define your architectural rule
16 */
17 public static function rule(): ArchRule
18 {
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 rule
27 */
28 public static function path(): string
29 {
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.

Mathieu De Gracia avatar
Mathieu De Gracia
Des fois, mon chat code à ma place

A lire

Autres articles de la même catégorie