Créer un nouveau module Laravel
Guide complet étape par étape pour créer un nouveau module conforme aux standards et conventions du projet.
1. Vue d'ensemble
Prérequis
- • Compréhension de Laravel
- • Connaissance des patterns
- • Environnement configuré
Temps estimé
- • Module simple : 30-45 min
- • Module moyen : 1-2 heures
- • Module complexe : 2-4 heures
Structure finale
Dossiers standardisés : Actions, Queries, Models, Policies, Enums, Events, etc.
2. Structure d'un module
app/Specifics/ModuleName/
├── Actions/ # Actions métier atomiques
├── Commands/ # Commandes Artisan (optionnel)
├── Controllers/ # Contrôleurs HTTP (optionnel)
├── DTO/ # Data Transfer Objects (optionnel)
├── Enums/ # Énumérations
├── Events/ # Événements
├── Factories/ # Factories pour tests
├── Listeners/ # Écouteurs d'événements (optionnel)
├── Models/ # Modèles Eloquent
├── Observers/ # Observers Eloquent (optionnel)
├── Policies/ # Policies d'autorisation
├── Queries/ # Queries pour récupération de données
├── Requests/ # Form Requests (optionnel)
└── Services/ # Services métier complexes (optionnel)
3. Étapes de création
Étape 1 : Planification
Avant de commencer, définissez :
- Nom du module : PascalCase, singulier (ex:
Product,Order) - Entité principale : Le modèle principal
- Fonctionnalités : Liste des fonctionnalités à implémenter
- Dépendances : Modules dont dépend ce module
Étape 2 : Créer la structure de base
Créer les dossiers :
# Depuis la racine du projet
mkdir -p app/Specifics/Products/{Actions,Commands,Controllers,DTO,Enums,Events,Factories,Listeners,Models,Observers,Policies,Queries,Requests,Services}
# Créer les fichiers .gitkeep dans les dossiers vides
touch app/Specifics/Products/{Commands,Controllers,DTO,Listeners,Observers,Requests,Services}/.gitkeep
Ou utiliser la commande Artisan :
php artisan make:module Products
Étape 3 : Créer le modèle principal
Fichier : app/Specifics/Products/Models/Product.php
namespace App\Specifics\Products\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
class Product extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = [
'name',
'description',
'price',
'status',
'user_id',
];
protected function casts(): array
{
return [
'price' => 'decimal:2',
'status' => ProductStatus::class,
];
}
protected static function newFactory()
{
return ProductFactory::new();
}
}
Étape 4 : Créer la migration
php artisan make:migration create_products_table
Étape 5 : Créer les Enums
Fichier : app/Specifics/Products/Enums/ProductStatus.php
enum ProductStatus: string
{
case DRAFT = 'draft';
case PUBLISHED = 'published';
case ARCHIVED = 'archived';
public function label(): string
{
return match ($this) {
self::DRAFT => 'Brouillon',
self::PUBLISHED => 'Publié',
self::ARCHIVED => 'Archivé',
};
}
public function color(): string
{
return match ($this) {
self::DRAFT => 'gray',
self::PUBLISHED => 'success',
self::ARCHIVED => 'warning',
};
}
}
Étape 6 : Créer les Actions
Utiliser la commande Artisan :
php artisan make:action Products CreateProductAction
php artisan make:action Products UpdateProductAction
php artisan make:action Products DeleteProductAction
Exemple d'Action :
class CreateProductAction
{
public function execute(User $user, array $data): Product
{
$data['user_id'] = $user->id;
return DB::transaction(function () use ($data) {
$product = Product::create($data);
event(new ProductCreated($product));
return $product;
});
}
}
Étape 7 : Créer les Queries
Utiliser la commande Artisan :
php artisan make:query Products GetProductListQuery
php artisan make:query Products GetProductDetailQuery
Exemple de Query :
class GetProductListQuery
{
public function execute(
?ProductStatus $status = null,
?string $search = null,
int $perPage = 15
): LengthAwarePaginator {
$query = Product::with(['user']);
if ($status) {
$query->where('status', $status);
}
return $query->orderBy('created_at', 'desc')
->paginate($perPage);
}
}
Étape 8 : Créer les Policies
Fichier : app/Specifics/Products/Policies/ProductPolicy.php
class ProductPolicy
{
public function viewAny(User $user): bool
{
return $user->hasPermissionTo('view-products');
}
public function create(User $user): bool
{
return $user->hasPermissionTo('create-products');
}
public function update(User $user, Product $product): bool
{
return $user->hasPermissionTo('update-products')
|| ($product->user_id === $user->id
&& $user->hasPermissionTo('update-own-products'));
}
}
Enregistrer dans app/Providers/AuthServiceProvider.php
4. Commandes Make personnalisées
make:action
Génère une nouvelle classe Action pour un module spécifique.
php artisan make:action {module} {name}
# Exemples
php artisan make:action Products CreateProductAction
php artisan make:action FeedbackHub UpdateFeedbackStatusAction
✅ Génère automatiquement le namespace correct
✅ Extrait l'entité du nom de l'Action
✅ Ajoute automatiquement le suffixe "Action" si manquant
make:query
Génère une nouvelle classe Query pour un module spécifique.
php artisan make:query {module} {name}
# Exemples
php artisan make:query Products GetProductListQuery
php artisan make:query FeedbackHub GetFeedbackDetailQuery
✅ Génère automatiquement le namespace correct
✅ Ajoute automatiquement le préfixe "Get" et suffixe "Query" si manquants
make:service
Génère une nouvelle classe Service pour un module spécifique.
php artisan make:service {module} {name}
# Exemples
php artisan make:service Products ProductService
php artisan make:service Email ContactSyncService
✅ Génère automatiquement le namespace correct
✅ Injection de dépendances configurée
✅ Méthodes de base générées
make:module
Génère un module complet avec toute sa structure de dossiers et fichiers de base.
php artisan make:module {name} {entity?}
# Exemples
php artisan make:module Products Product
php artisan make:module Orders
✅ Génère toute la structure de dossiers standardisée
✅ Crée les fichiers de base (Model, Enum, Policy, Factory)
✅ Ajoute les fichiers .gitkeep dans les dossiers optionnels
make:dto
Génère une nouvelle classe DTO pour un module spécifique.
php artisan make:dto {module} {name}
# Exemples
php artisan make:dto Products CreateProductData
php artisan make:dto FeedbackHub UpdateFeedbackData
✅ Propriétés readonly pour l'immutabilité
✅ Méthodes toArray() et fromArray() incluses
make:filament-resource
Génère une Resource Filament complète avec Pages, Schemas et Tables.
php artisan make:filament-resource {module} {entity} [--panel=admin]
# Exemples
php artisan make:filament-resource FeedbackHub Feedback --panel=admin
php artisan make:filament-resource Products Product --panel=app
✅ Génère toute la structure Filament
✅ Crée les 3 Pages (List, Create, Edit)
✅ Crée le Schema et la Table
5. Checklist de validation
Structure
- Tous les dossiers requis sont créés
- Fichiers .gitkeep dans les dossiers vides
- Structure conforme à l'architecture
Modèle
- Modèle créé avec namespace correct
- Factory créée et enregistrée
- Migration créée et exécutée
Actions & Queries
- Actions créées avec namespace correct
- Queries créées avec eager loading
- Transactions DB utilisées
Policies & Tests
- Policy créée et enregistrée
- Tests créés pour les Actions
- Tous les tests passent
6. Exemples de modules de référence
Module simple : Blog
Structure claire et minimale, bon exemple pour commencer.
- • app/Specifics/Blog/Models/Post.php
- • app/Specifics/Blog/Actions/CreatePostAction.php
- • app/Specifics/Blog/Queries/GetPublishedPostsQuery.php
Module complet : FeedbackHub
Structure très complète, tous les patterns utilisés.
- • app/Specifics/FeedbackHub/Models/Feedback.php
- • app/Specifics/FeedbackHub/Actions/CreateFeedbackAction.php
- • app/Specifics/FeedbackHub/Queries/GetFeedbackListQuery.php
Module avec DTO : Realtime
Utilisation de DTOs, bon exemple d'architecture.
- • app/Specifics/Realtime/DTO/CreateRoomData.php
- • app/Specifics/Realtime/Actions/CreateChatRoomAction.php
7. FAQ
Dois-je créer tous les dossiers ?
Non, créez seulement les dossiers nécessaires. Les dossiers minimaux sont : Models/, Enums/, Policies/, Actions/ et Queries/.
Quand utiliser un Service ?
Utilisez un Service quand vous devez orchestrer plusieurs Actions/Queries, quand la logique métier est complexe, ou quand vous avez des intégrations externes multiples.
Quand utiliser un DTO ?
Utilisez un DTO quand vous avez des données complexes à passer entre couches, quand vous voulez garantir la structure des données, ou quand vous avez besoin de validation centralisée.
Comment tester mon module ?
Créez les tests dans tests/Feature/Specifics/{ModuleName}/, utilisez les factories pour créer les données de test, et exécutez : php artisan test --filter={ModuleName}
8. Commandes utiles
# Créer un module complet
php artisan make:module Products
# Créer une migration
php artisan make:migration create_products_table
# Créer une factory
php artisan make:factory ProductFactory --model=App\\Specifics\\Products\\Models\\Product
# Exécuter les migrations
php artisan migrate
# Exécuter les tests
php artisan test --filter=Products
# Formater le code
./vendor/bin/pint app/Specifics/Products/
Support
En cas de question ou problème :
- Consultez les modules de référence (Blog, FeedbackHub)
- Vérifiez la documentation de l'architecture
- Contactez l'équipe de développement